Светодиодная доска с адресными светодиодами - Своими руками
Своими руками

Светодиодная доска с адресными светодиодами

>

Светодиодная доска с адресными светодиодамиС помощью этой светодиодной доски можно создавать пиксельные рисунки. С помощью поворота двух энкодеров осуществляется управление горизонтальным и вертикальным положением курсор. Для изменения цвета энкодер необходимо нажать. Все это контролируется Arduino Nano.
Инструменты и материалы:-Arduino Nanо;-Два поворотных энкодера с нажимным переключателем;-Две ручки для энкодеров;-Светодиодная матрица WS2812b 16 x 1;
-Макетная плата;-Перемычки -15 шт;-Источник питания;
-МДФ;
-Клей ПВА;
-Красная краска;
-Клеевой пистолет;
Шаг первый: схема
Сначала мастер проверил схему, используя макетную плату. Для светодиодной матрицы нужно использовать дополнительный источник питания, хотя мастер запитал ее напрямую Arduino.
Светодиодная доска с адресными светодиодамиСветодиодная доска с адресными светодиодамиШаг второй: код
Для работы матрицы потребуется установить библиотеки FastLED и LEDMatrix .
Не все светодиодные матричные панели имеют одинаковую конфигурацию. Библиотека LEDMatrix включает в себя различные конфигурации, нужно поэкспериментировать со строками 14, 15 и 16.
Код можно скачать ниже.
Светодиодная доска с адресными светодиодами Показать / Скрыть текст// RGB LED Etch-A-Sketch
// Author: John-Lee Langford
// Website: www.mr.langford.co

// Includes
#include <FastLED.h> // https://github.com/FastLED/FastLED
#include <LEDMatrix.h> // https://github.com/AaronLiddiment/LEDMatrix

// Change the next 6 defines to match your matrix type and size
#define LED_PIN 10
#define COLOR_ORDER GRB
#define CHIPSET WS2812

#define MATRIX_WIDTH -16 // Set this negative if physical led 0 is opposite to where you want logical 0
#define MATRIX_HEIGHT -16 // Set this negative if physical led 0 is opposite to where you want logical 0
#define MATRIX_TYPE VERTICAL_ZIGZAG_MATRIX // See top of LEDMatrix.h for matrix wiring types

cLEDMatrix<MATRIX_WIDTH, MATRIX_HEIGHT, MATRIX_TYPE> leds;

// Rotary A – Horizontal movement
int horizontalA = 9; // DT
int horizontalB = 8; // CLK
int buttonA = 7; // Button
int btnA; // Button A value
int horizontalALast;
int horizontal, horizontalCursor = 0;
unsigned char encoder_horizontalA;
unsigned char encoder_horizontalB;
unsigned char encoder_horizontalA_prev = 0;

// Rotary B – Vertical movement
int verticalA = 6; // DT
int verticalB = 5; // CLK
int buttonB = 4; // Button
int btnB; // Button B value
int verticalALast;
int vertical, verticalCursor = 0;
unsigned char encoder_verticalA;
unsigned char encoder_verticalB;
unsigned char encoder_verticalA_prev = 0;

// Common
unsigned long currentTime;
unsigned long loopTime;
bool moved = false;

// Colours
const int numberColours = 9; // Total number of colours available
unsigned long colours[numberColours][2] = {
{0xFF0000, 0x330000},
{0xFF6600, 0x331100},
{0xFFFF00, 0x333300},
{0x00FF00, 0x003300},
{0x00FFFF, 0x001111},
{0x0000FF, 0x000033},
{0xFF00FF, 0x330033},
{0xFFFFFF, 0x111111},
{0x111111, 0x000000}
};
int currentColour = 0; // Set to first colour in array

void setup() {

FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds[0], leds.Size());
FastLED.setBrightness(255);

// Clear the display in a pretty way
int colourBounce = 1;
for (int i = 0; i < 16; i++){
leds.DrawLine(0, i, 15, i, colours[currentColour][0]);
leds.DrawLine(i, 0, i, 15, colours[currentColour][0]);
FastLED.show();
delay(25);
leds.DrawLine(0, i, 15, i, CRGB(0, 0, 0));
leds.DrawLine(i, 0, i, 15, CRGB(0, 0, 0));
currentColour = currentColour + colourBounce;
if (i == 7) {
colourBounce = -1;
}

}

FastLED.clear(true);

// Rotary A – Horizontal
pinMode (horizontalA, INPUT);
pinMode (horizontalB, INPUT);
pinMode (buttonA, INPUT);
horizontalALast = digitalRead(horizontalA);

// Rotary B – Vertical
pinMode (verticalA, INPUT);
pinMode (verticalB, INPUT);
pinMode (buttonB, INPUT);
verticalALast = digitalRead(verticalA);

// Common
currentTime = millis();
loopTime = currentTime;
}

void loop() {
// get the current elapsed time
currentTime = millis();
if (currentTime >= (loopTime + 5)) {
// Read encoder pins
encoder_horizontalA = digitalRead(horizontalA);
encoder_horizontalB = digitalRead(horizontalB);
encoder_verticalA = digitalRead(verticalA);
encoder_verticalB = digitalRead(verticalB);

// Check for button presses
btnA = digitalRead(buttonA);
btnB = digitalRead(buttonB);

if (btnA == 0) {
currentColour++;
if (currentColour > (numberColours – 1)) {
currentColour = 0;
}
delay(500);
}

if (btnB == 0) {
currentColour–;
if (currentColour < 0) {
currentColour = numberColours – 1;
}
delay(500);
}

// Encoder A
if ((!encoder_horizontalA) && (encoder_horizontalA_prev)) {
// A has gone from high to low
if (encoder_horizontalB) {
// B is high so counter-clockwise
if (horizontalCursor > 0) {
horizontalCursor –;
moved = true;
}
}
else {
// B is low so clockwise
if (horizontalCursor < 15) {
horizontalCursor ++;
moved = true;
}
}

}
encoder_horizontalA_prev = encoder_horizontalA; // Store value of A for next time

// Encoder B
if ((!encoder_verticalA) && (encoder_verticalA_prev)) {
// C has gone from high to low
if (encoder_verticalB) {
// B is high so counter-clockwise
if (verticalCursor < 15) {
verticalCursor ++;
moved = true;
}
} else {
// D is low so clockwise
if (verticalCursor > 0) {
verticalCursor –;
moved = true;
}
}
}

encoder_verticalA_prev = encoder_verticalA; // Store value of C for next time
loopTime = currentTime; // Updates loopTime

leds(horizontalCursor, verticalCursor) = colours[currentColour][0];

// Move the LED
if (moved) {
leds(horizontal, vertical) = colours[currentColour][1];
horizontal = horizontalCursor;
vertical = verticalCursor;
moved = false;
}

FastLED.show();
}
}Шаг третий: рамка
Для изготовления рамки мастер использовал 6-миллиметровые листы МДФ. Сначала он отрезал четыре листа размером А4. Затем, отступив от края 2,5см, вырезал у трех заготовок середину. Эти три листа, когда они склеены, должны обеспечивать достаточную глубину для размещения Arduino и других компонентов.
Дальше четыре листа МДФ были склеены с помощью клея ПВА. Когда ПВА полностью затвердел, отшлифовали края.
В передней части корпуса просверлил отверстия. Два, по краям, для энкодеров. Три центральных, для проводов.
Покрасил рамку в красный цвет.
Светодиодная доска с адресными светодиодамиСветодиодная доска с адресными светодиодамиСветодиодная доска с адресными светодиодамиШаг четвертый: сборка
Чтобы устройство было как можно более тонким, мастер использовал тонкие полоски перфорированной платы (1 x 4) для питания.
Энкодеры прикручиваются с помощью гаек входящих в комплект, остальные детали крепятся с помощью термоклея.
Светодиодная доска с адресными светодиодамиШаг пятый: управление
Управляется матрица следующим образом.
При повороте левого энкодера курсор перемещается влево и вправо. Нажатие на энкодер перемещает курсор вперед.
При повороте правого энкодера курсор перемещается вверх и вниз. Нажатие на энкодер перемещает курсор назад.
Когда курсор перемещается, выбранный цвет остается в предыдущем «пикселе».
Курсор отображается ярче, чем другие пиксели, поэтому пользователи могут видеть, где он находится.
Светодиодная доска с адресными светодиодами

SitesReady

Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного. - Альберт Эйнштейн

Follow us

Don't be shy, get in touch. We love meeting interesting people and making new friends.