Контроль яскравості 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 штук.

В результаті:

Оскільки це був перший досвід пайки, вийшло кривувато, але певне задоволення від процесу отримав. Але як же було моє розчарування, коли виявилося, що не всі "стовпці" горять, хоча перед пайкою кожен світлодіод був перевірений. При відпаяні та перевірці окремо від куба (особливо) червоні не захотіли загорітися. При ретельному огляді виявилося, що в деяких важкодоступних місцях катоди дотикалися до анодів і взагалі все сумно. Тому дуже важливо максимально однаково зігнути всі світлодіоди до початку пайки в шаблоні.

Покопавшись пару годин, зрозумів, що зробити новий буде набагато простіше.

У другому 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);
  }

Ось що вийшло в результаті:

В результаті вийшла цікава річ, яка створює "вау" ефект і особливо в свята радує око. Сподіваюся, мій досвід буде комусь цікавий і корисний.

Top