Контроль яркости LED — куба

В данной статье я хотел бы поделиться своим опытом создания полноценного светодиодного (так называемого LED) куба с возможностью регулировки и контроля яркости светодиодов. Это мой первый опыт работы с Arduino UNO и вообще с «железячным» проектом. При прощупывании и выбирании темы именно обилие разных «огоньков» в виде четкой и строгой структуры куба произвели наибольшый «вау»-эффект, поэтому было решено сделать именно LED-куб. Из-за того, что нашлось куча туториалов именно о LED-кубе с светомузыкой, захотелось сделать что-то более оригинальное и интересное, поэтому решил сделать LED-куб разноцветным с различными слоями цветов и контролировать яркость каждого слоя-цвета.

Список «ингредиентов»

  • Arduino UNO или аналоги
  • 300 светодиодов, по 100 штук каждого цвета.
  • сдвиговый регистр 74HC595 x 4 штуки
  • датчик дистанции HC-SR04 x 3 штуки
  • резисторы на 120 ОМ x 20 штук, резисторы на 180 ОМ x 20 штук
  • алюминиевая проволока
  • провода

Точно такого примера проекта, как я задумал в интернете аналогов не нашел, поэтому пришлось все разрабатывать с нуля. Было заказано 500 светодиодов, по 100 штук белого, красного, синего, зеленого, желтого цветов. Так как хотелось сделать максимально разноцветное сочетание, из которого издалека можно попробовать сделать любой цвет, то решил делать красный, синий и зеленые слои- цвета размером 5x5x5. Все использованные светодиоды были 3 мм, красные и желтые по 2 В, зеленые и синие по 3 В .

Пайка LED-куба

Не мудрствуя лукаво, быстро просмотрев правильные схемы включения светодиодов в цепочки, понял, что изобретать велосипед совсем не хочется, поэтому решил использовать классическую схему соединения LED-куба слоями с параллельным соединением светодиодов.

Хотя подробных статей про сборку своего «ящика Пандоры» вагон и маленькая тележка, все-таки хочу вкратце рассказать:

Шаблон:

Катоды сгибаются в горизонтальное положение, аноды в вертикальное. Очень важно согнуть все светодиоды по одной схеме, максимально одинаково, чтобы не иметь потом проблем при пайке слоев между собой.

Таких слоев должно быть 5 штук.

В итоге:

Так как это был первый опыт пайки получилось кривовато, но определенное удовольствие от процесса получил. Но каково же было мое огорчение, когда оказалось, что не все «столбцы» горят, хотя перед пайкой каждый светодиод был проверен. При отпайке и проверке отдельно от куба (особенно) красные не захотели загореться. При тщательном осмотре оказалось,что в некоторых труднодоступных местах катоды прикасались к анодам и вообще все печально. Потому очень важно <b>максимально одинаково</b> согнуть все светодиоды до начала пайки в шаблоне.

Поковырявшись пару часов, понял, что сделать новый будет гораздо проще.

Во втором Led-кубе я решил отказаться от красных светодиодов в пользу желтых.

Вот что вышло:

Ну и собственно «стар и млад»:

Радости было много как никогда, когда «елочка зажглась»:

Контроль яркости

Как известно у Arduino UNO 14 цифровых, среди которых 6 могу генерировать ШИМ, и 6 аналоговых выходов. Было решено не париться с аналоговыми и использовать ШИМ. В итоге 3 ШИМ выхода ушло на 3 датчика дистанции ( о которых чуть позже) и 3 соответственно на контроль каждого слоя.

Для контроля каждого слоя были использованы регистры сдвига 74HC595

Информацию о работе с этим простейшим сдвигом можно почитать здесь

Сам регистр:

Суть в том, что у регистра есть магический вход OE, который отвечает за высокоимпедансное состояние выходов регистра, подавая на который ШИМ сигнал можно добиться ШИМ на всех 8 выходах 74HC595.

Датчики дистанции HC-SR04

Принцип действия прост: на пин TRIG подается сигнал, который «выстреливает» из одной «плашки», вторая плашка принимает и соответственно результат передает через выход ECHO, который нужно подключить к пину с ШИМ в ардуино. Документация по датчику здесь.

Схема подключения

Схема получилась громоздкой, поэтому требует пояснений. Так как зеленых столбцов куба у нас 7 , синих 6, а желтых 12, то подключаем зеленые к Q1..Q7 выходам первого регистра, синие к выходам второго, ну и соответственно желтые столбцы подключаются к выходам 2 регистров. Для каждого столбца обязателен резистор; для синих и зеленых 120 ОМ, для желтых на 180 Ом. На кубе необходимо вертикально припаять полоску проволоки к горизонтальным слоям для создания общей земли, которую пускаем на gnd соответственно.

Конфигурационные входы всех сдвиговых регистров STCP, SHCP, DS и MR подключается вместе к выходам: STCP к 12;
SHCP к 13, DS к 8, MR на VCC.

OE регистра для синих светодиодов на 11 выход, для желтых на 10 и зеленых на 9 выходы арудино.

Выходы датчиков дистанции trigg_blue к 7, echo_blue к 6, echo_green к 5, trigg_green к 4, echo_yellow к 3, yellow к 2 выходам ардуино. Ну и соответственно gnd и vcc на gnd и vcc.

Пайка

Для удобства куб был нанизан на макетную плату, ну и на ней собственно все паялось. 

Код

Собственно датчики дистанции работают до 400 см, но я решил ограничиться 50 см.

int DS_pin = 8;
int STCP_pin = 12;
int SHCP_pin = 13;
int blue = 11;
int yellow = 10;
int green = 9;

int trigg_blue = 7;
int echo_blue = 6;

int echo_green = 5;
int trigg_green = 4;

int echo_yellow = 3;
int trigg_yellow = 2;

void setup()  {
 pinMode(DS_pin,OUTPUT);
 pinMode(STCP_pin,OUTPUT);
 pinMode(SHCP_pin,OUTPUT);
 pinMode(blue,OUTPUT);
 pinMode(green,OUTPUT);
  pinMode(yellow,OUTPUT);
 Serial.begin(9600);
 while (!Serial) {
 }

 pinMode(trigg_blue, OUTPUT);
 pinMode(echo_blue, INPUT);

  pinMode(trigg_green, OUTPUT);
 pinMode(echo_green, INPUT);

  pinMode(trigg_yellow, OUTPUT);
 pinMode(echo_yellow, INPUT);

   digitalWrite(STCP_pin, LOW);
 shiftOut(DS_pin, SHCP_pin, MSBFIRST, 0xFF);  digitalWrite(STCP_pin, HIGH);
}

void loop()
{
 long duration_green, distance_green;
 digitalWrite(trigg_green, LOW);  delayMicroseconds(2);
 digitalWrite(trigg_green, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigg_green, LOW);
 duration_green = pulseIn(echo_green, HIGH);
 distance_green = (duration_green/2) / 29.1;  long duration_blue, distance_blue;
 digitalWrite(trigg_blue, LOW);  delayMicroseconds(2);
 digitalWrite(trigg_blue, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigg_blue, LOW);
 duration_blue = pulseIn(echo_blue, HIGH);
 distance_blue = (duration_blue/2) / 29.1;

 long duration_yellow, distance_yellow;
 digitalWrite(trigg_yellow, LOW);  delayMicroseconds(2);
 digitalWrite(trigg_yellow, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigg_yellow, LOW);
 duration_yellow = pulseIn(echo_yellow, HIGH);
 distance_yellow = (duration_yellow/2) / 29.1;
   if(distance_green > 50 || distance_green < 0){
  analogWrite(green, 254);
 } else analogWrite(green, distance_green*5);

 if(distance_yellow > 50 || distance_yellow < 0){
  analogWrite(yellow, 254);
 } else analogWrite(yellow, distance_yellow*5);

 if(distance_blue > 50 || distance_blue < 0){
  analogWrite(blue, 254);
 } else analogWrite(blue, distance_blue*5);
 delay(200);
  }

Вот что получилось в итоге:

В итоге получилась интересная вещь, которая создает «вау» эффект и особенно в праздники радует глаз. Надеюсь мой опыт будет кому-нибудь интересен и полезен.

Добавить комментарий

Ваш адрес email не будет опубликован.