Któż nie lubi migających zabawek. Jakiś czas temu tworzyłem Led Staff czyli kij z ledowymi światłami gdzie każda dioda może być indywidualnie programowana przy wykorzystaniu bluetooth tworząc dowolne wzory. Poniżej instruktaż jak zbudować taki kij.
Materiały:
1 x Atmega 328P-PU
1x 5V Micro USB 18650 Lithium Battery Charging Board Protection
1x 18650 Bateria
1x HC-05 Wireless Bluetooth RF Transceiver
2m Taśmy Led WS2812B Ditigal RGB Pixel 5050
1x przełącznik on-off
2x 22nf kondensator
1x 16 MHz rezonator kwarcowy
1 x rezystor 2,2K omów
2 x rezystor 10K omów
1x pręt metalowy 1,5m, 6mm
1x Rura plexi średnica zewnętrzna 30/2 mm
2x Zaślepki do rurki fi 30
Przedmioty niezbędne do wytrawienia płytki drukowanej
Schemat dla całej konstrukcji wraz z płytką drukowaną jest następujący:
Jak wiele tworzonych przeze mnie projektów opartych o moduł Atmega 328 podstawę stanowi Breduino o którego konstrukcji można poczytać więcej pod tym adresem httpss://www.arduino.cc/en/Main/Standalone
Do niego podłączone mamy dwa moduły są nimi indywidualnie programowalne taśmy ledowe 5050 oraz moduł HC-05 odpowiedzialny za komunikację bluetooth, wszystko możliwe do włączenia i wyłączenia za pomocą przełącznika typu on-off.
W zależności od tego jaki kij ledowy chcemy stworzyć takie musimy kupić taśmy ledowe. Na rynku znajdziemy kilka rodzajów taśm. Taśmy dzielą się głównie w zależności od liczby posiadanych diód na metr (zazwyczaj 30/60/120/144 na metr), rodzajem zastosowanej diody (3528,5050,5630 itp. Liczby odpowiadają wielkości diody np. dioda 3528 to dioda o wymiarach 3,5×2,8 milimetra), szybkością odswiezania (Mhz), czy są indywidualnie programowalne czy programowane są tylko całe pasma, kolorem (jednokolorowe, RGB), napięciem (5V, 12V).
W przypadku tego projektu zostały wykorzystane taśma posiadająca 60 diód na metr WS2812B RGB 5050 5V Indywidualnie adresowana. Na ebay można je znaleźć w granicach 50 zł za metr. Jeśli chcemy zaoszczędzić możemy zainstalować jednokolorowe taśmy są one znacznie tańsze jednak nie osiągniemy w nich wielu ciekawych efektów, zwykle działają też na 12V. Sterowniki WS2812 powinny wystarczać do większości zastosowań z wyjątkiem jeśli chcielibyśmy mieć kij dający efekt Persistence of Vision (pixel poi) niestety do tego celu ich odświeżanie jest zbyt małe i konieczne byłoby zainwestowanie w droższe taśmy oparte na sterownikach LPD8806 (ok 120 zł za metr i raczej nie znajdziemy taśm posiadających więcej diód niż 60/metr). Niemniej jeśli zainwestujemy w droższe taśmy pozostała część konstrukcji pozostaje bez zmian.
Taśma taka posiada trzy wyjścia są nimi zasilanie 5V, uziemienie oraz wyjście na dane. W przypadku 5V i uziemienia rozwiązanie powinno być oczywiste. Dane podłączamy do jednego z wyjść Arduino w moim wypadku jest to wyjście 15.
Kolejny moduł to moduł bluetooth. Osobiście polecam HC-05 jest to tani moduł który na e-bayu można kupić już za około 3-5 dolarów, niestety przy tej cenie aby wszystko nam działało należy przedtem odpowiednio go skonfigurować. W tym celu odwołuje się do innego instruktażu z którym warto się zapoznać https://makezine.com/projects/diy-arduino-bluetooth-programming-shield/
Na koniec dodajemy zwykły przycisk on-off i zasilanie. Gotowy schemat wytrawiamy korzystając z tych instrukcji: https://binaryalchemist.pl/jak-wytrawic-plytke-drukowana/
W ten sposób mamy przygotowaną płytkę pozostaję nam jedynie zmontowanie kija. Jako podstawę wykorzystujemy pręt metalowy o długości 1,5m i średnicy 6mm. Żeby oddzielić metal od reszty i poprawić jego wygląd warto go obwinąć taśma termoizolacyjną. Na jego środku umieszczamy gotową płytkę która możemy unieruchomić również taśma izolacyjna. Następnie na jego końcach montujemy taśmy ledowe. Taśmy podzielone są na 4 odcinki po 30 diód połączone kablami. Zasilanie pochodzi z baterii 18650. Aby ładowanie kija było jak najprzyjemniejsze najlepiej przygotować niewielki pojemnik na baterie oraz skorzystać z modułu „18650 Lithium Battery Charging Board” jego podłączenie jest bardzo proste a dzięki niemu możemy szybko i prosto ładować baterie bez konieczności demontażu. Włącznik i wyłącznik znajduję się w jednej z zaślepek. Całość wkładamy do zamówionej w internecie rury plexi śr. zewnętrzna 30 mm/2.
Każda dioda jest możliwa do indywidualnego zaprogramowania dzięki czego można tworzyć praktycznie nieskończoną liczbę efektów kod źródłowy wygląda następująco, przedtem jednak sciągnijmy następującą bibloteke httpss://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library-installation:
#include <Adafruit_NeoPixel.h>
#define PIN 11
Adafruit_NeoPixel strip = Adafruit_NeoPixel(108, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
strip.show();
}
void loop() {
colorWipe(strip.Color(255, 0, 0), 50);
colorWipe(strip.Color(0, 255, 0), 50);
colorWipe(strip.Color(0, 0, 255), 50);
theaterChase(strip.Color(127, 127, 127), 50);
theaterChase(strip.Color(127, 0, 0), 50);
theaterChase(strip.Color( 0, 0, 127), 50);
rainbow(20);
rainbowCycle(10);
rainbow(10);
rainbowCycle(5);
theaterChaseRainbow(50);
feuerfrei(strip.Color(40,0, 0), strip.Color(0, 0, 255),100,20);
}
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}
void rainbow(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256; j++) {
for(i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, Wheel((i+j) & 255));
}
strip.show();
delay(wait);
}
}
void rainbowCycle(uint8_t wait) {
uint16_t i, j;
for(j=0; j<256*5; 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);
}
}
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; 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
}
}
}
}
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; 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
}
}
}
}
void feuerfrei(uint32_t c, uint32_t c2, uint32_t repete, uint8_t wait) {
for (int rep = 0; rep < repete; rep++) {
int e = random(0, 27);
int f = random(28, 54);
int g = random(55, 81);
int h = random(82, 108);
for (int i = 0; i < 27; i++) {
for (int no = 0; no < 108; no++) {
strip.setPixelColor(no, c);
//strip.setPixelColor(no, strip.Color(0, 255, 0));
}
if (e + i < 27) { strip.setPixelColor(e + i, c2); } if (e - i >= 0) {
strip.setPixelColor(e - i, c2);
}
if (f + i < 54) { strip.setPixelColor(f + i, c2); } if (f - i >= 27) {
strip.setPixelColor(f - i, c2);
}
if (g + i < 81) { strip.setPixelColor(g + i, c2); } if (g - i >= 54) {
strip.setPixelColor(g - i, c2);
}
if (h + i < 108) { strip.setPixelColor(h + i, c2); } if (h - i >= 81) {
strip.setPixelColor(h - i, c2);
}
strip.show();
delay(wait);
}
}
}
void nieustraszony(uint32_t c, uint8_t wait){
int val;
int val2;
int val3;
for(uint16_t i=0; i<15; i++) {
val = 29-i;
val2=30+i;
val3=59-i;
strip.setPixelColor(i, c);
strip.setPixelColor(val, c);
strip.setPixelColor(val2, c);
strip.setPixelColor(val3, c);
for(uint16_t j=0; j<60; j++) { if(i!=j&&j!=val&&j!=val2&&j!=val3){ strip.setPixelColor(j, strip.Color(0,0,0)); } } strip.show(); delay(wait); } for(uint16_t i=15; i>1; i--) {
val = 31-i;
val2=61-i;
val3=28+i;
strip.setPixelColor(i, c);
strip.setPixelColor(val, c);
strip.setPixelColor(val2, c);
strip.setPixelColor(val3, c);
for(uint16_t j=0; j<60; j++) {
if(i!=j&&j!=val&&j!=val2&&j!=val3){
strip.setPixelColor(j, strip.Color(0,0,0));
}
}
strip.show();
delay(wait);
}
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
}
Gotowy projekt prezentuję się następująco:
Ciekawe Referencje:
Eagle schematy
Kod zródłowy