مقدمه
کدام ویژگی، الایدیهای RGB را به قطعهای جذاب و کاربردی در صنعت الکترونیک و نورپردازی تبدیل ساخته است؟
پاسخ: قابلیت منحصر به فرد این قطعات در کنترل میزان سه رنگ اصلی (قرمز، سبز و آبی) برای ایجاد یک رنگ دلخواه. یک الایدی RGB شامل یک پایه مشترک و سه پایه برای روشنایی رنگهای قرمز، سبز و آبی است. با کنترل این پایهها با سیگنال پالس PWM، می توان رنگهای بیشماری را با ترکیب رنگهای اصلی به دست آورد. (تعداد رنگها بستگی به دقت سیگنال PWM تولیدی دارد).
کنترل این قطعات با استفاده از میکروکنترلرها و درایورهای PWM انجام میشود. از آنجا که تعداد پایهها و جریان خروجی هر میکروکنترلری محدود است ماژولهای متنوعی جهت افزایش کانالهای PWM برای کنترل الایدیهای RGB طراحی شدهاند. اما باز هم محدودیتهای بسیاری برای کنترل تک تک الایدیهای RGB به صورت مجزا وجود دارد و یا اینکه هزینه انجام پروژه را بسیار بالا میبرد.

این مشکل در نسل بعدی الایدیهای RGB به نوعی حل شده است. الایدیهای سری WS1812، تکامل یافتۀ الایدیهای RGB محسوب میشوند که دارای یک کنترلر داخلی با همین نام هستند. ارتباط با این کنترلرهای “قابل برنامهریزی” و تنظیم رنگ الایدیها، تنها با یک خط دیتا انجام میشود. و از آن هم جذابتر اینکه با وجود قابلیت cascade و “آدرس دهی” در این الایدیها، تعداد زیادی از آنها را میتوان به هم متصل کرده و با همان یک خط ارتباطی، کنترل کرد.
الایدیهای سری WS2812، هم به صورت تکی و هم به صورت ماژولار، در تعداد و اشکال مختلف، در بازار موجود میباشند که استفاده از این تکنولوژی جذاب را برای پروژههای مختلف آسان نموده اند.

نئوپیکسل چیست؟
برای کنترل هر LED RGB به سه پایه دیجیتال از میکروکنترلر (یا بوردهای توسعه یافته مانند آردوینو) نیاز دارید. بنابراین اگر بخواهید بعنوان مثال برای کنترل یک رشته LED RGB شامل 60 LED بنحوی که بتوانید رنگ هر LED را جداگانه کنترل کنید، به 180 پایه دیجیتال نیاز دارید! بنابراین باید کنترل هر LED بصورت جداگانه را فراموش کنید و یا از LED های آدرس پذیر استفاده کنید.
LED های آدرس پذیر، نسل جدیدی از LEDها هستند که علاوه بر LED RGB شامل یک آی سی کنترلی نیز می باشند. این آی سی کنترلی که معمولا WS2812 می باشد ، با اختصاص یک آدرس به هر LED و فراهم سازی ارتباط تک سیمه (One wire) به شما اجازه می دهد با استفاده از تنها یک پایه دیجیتال به تعداد زیادی LED بصورت جداگانه دسترسی داشته باشید، البته این نوع LED ها برخلاف LED های ساده تنها با اعمال ولتاژ روشن نمی شوند و برای روشن شدن نیاز به یک میکروکنترلر دارند.
نئوپیکسل، برند شرکت Adafruit برای LED های آدرس پذیر است.
مشخصات فنی و دیتاشیت WS2812
- ولتاژ ورودی: 5ولت (یا بازه 4 تا 7 ولت)
- پکیج الایدی: 5050
- جریان مصرفی هر الایدی در حداکثر حالت روشنایی: 60 میلی آمپر
- جریان مصرفی هر رنگ: 20mA * دیوتی سایکل آن رنگ
- فرکانس اسکن: حداقل 400Hz
- سرعت انتقال دیتا: 800Kbps
- Built-in electric reset circuit and power lost reset circuit
- پروتکل ارتباطی: NZR تک سیمه
برای اطلاعات دقیقتر به دیتاشیت ماژول مراجعه فرمایید.
تفاوت WS2812 و WS2812B
این الایدی ها در دو مدل متداول WS2812 و WS2812B موجود میباشند. WS2812B مدل رایجتری است. تفاوت این دو نیز تنها در تعداد و عملکرد پایههاست.
در مدل WS2812، تغذیه الایدی و تغذیه مدار کنترلی، جدا از هم است اما در مدل WS2812B این دو پایه، یکی شده است.

معرفی پایههای (Pinout) ماژول/الایدی WS2812(B)
این پایهها در مدل 6 پین عبارتند از:
- VSS: زمین مدار (Ground)
- VDD: تغذیه مثبت الایدی
- VCC: تغذیه مثبت مدار کنترلی
- NC: به جایی متصل نیست!!
- (DIN/IN/DI) Data In: پایه ورودی دیتا (یا از میکروکنترلر یا از طبقات قبلی)
- (DO/DOUT/OUT) Data Out: پایه خروجی دیتا (برای اتصال به طبقات بعدی)
این پایهها در مدل 4 پین عبارتند از :
- VCC/VDC : پایه مثبت تغذیه ماژول؛ 5 ولت در برخی ماژولها (4 تا 7 ولت نیز مناسب است)
- GND : زمین
- (DIN/IN/DI) Data In: پایه ورودی دیتا (یا از میکروکنترلر یا از طبقات قبلی)
- (DO/DOUT/OUT) Data Out: پایه خروجی دیتا (برای اتصال به طبقات بعدی)

لوازمی که به آن احتیاج دارید

در تهیه الایدیِ WS2812، هر مدلی را که مناسب پروژه شماست انتخاب کنید. تفاوتی در راهاندازی وجود ندارد.
قطعات مورد نیاز
نرم افزارهای مورد نیاز
راه اندازی ماژول WS2812 LED با آردوینو

همانطور که گفته شد راهاندازی تعداد زیادی از الایدی ها تنها با یک خط دیتا امکانپذیر بوده و اطلاعات از یک بلوک الایدی به بلوک دیگر منتقل میشود.
گام اول: نحوه عملکرد آردوینو با ماژول WS2812
اطلاعات رنگها به صورت متوالی از طریق پین دیجیتال آردوینو ارسال میشود. اولین الایدی مقدار اولین رنگ را دریافت کرده و متناسب با آن روشن میشود. باقی اطلاعت از طریق پین Dout به الایدی بعدی ارسال شده و به همین ترتیب انتقال اطلاعات ادامه مییابد. برای اتصال چند ماژول که هر کدام شامل چند الایدی هستند نیز کار به همین صورت است. آخرین الایدی ماژول قبلی اطلاعات را به اولین الایدی ماژول بعدی ارسال میکند و کار ادامه مییابد تا آخرین پیکسل موجود.

گام دوم: تغذیه مناسب
شاید اولین قدم در راهاندازی هر سیستمی، تهیه منبع تغذیه مناسب باشد.
ولتاژ مناسب راهاندازی این الایدیها همان 5 ولت است.
جریان مصرفی هر الایدی، حداکثر 60 میلیآمپر است. تعداد الایدیها ضرب در این عدد، مساوی است با جریان مورد نیاز برای الایدیها. به عنوان مثال برای راهاندازی 16 عدد از این الایدی ها، حداقل جریان منبع تغذیه باید 960mA (16*60mA=960mA) باشد.
پس یک منبع تغذیه 5 ولت 1 آمپر برای راهاندازی 16 عدد از این الایدیها کافیست.
گام سوم: سیم بندی WS2812 با آردوینو
مدار را مطابق شکل زیر ببندید.

یک مقاومت 300 تا 500 اهمی باید به ابتدای خط دیتا افزوده شود تا جریان کشی ناخواستهای اتفاق نیفتد. همین یک مقاومت هم برای کل ماژولها کافیست.
2- متصل کردن تغذیه آردوینو فراموش نشود!! اگر آردوینو به کامپیوتر وصل باشد، ولتاژش را از آن میگیرد اما اگر نیست به تغذیه مناسب متصل کنید. میتوانید از منبع تغذیه 5 ولت سوییچینگ هم استفاده کنید؛ کافیست پایه مثبت آن را به پایه 5v آردوینو متصل کنید. زمین مدار هم که در هر صورت باید یکی باشد.
3- اگر تغذیه سوییچینگ مدار از کیفیت بالایی برخوردار نبوده و ریپل ولتاژ خروجی بالایی دارد بین خطوط مثبت و زمین، یک خازن الکترولیت 1000 میکروفارادی متصل کنید.
خط دیتا در پروژه ما به پایه دیجیتال شماره 6 آردوینو متصل شده است. این پین قابل تغییر است. میتوانید از هر پین دیجیتال دلخواه استفاده کنید. فقط توجه داشته باشید که این پین در کد برنامه هم باید مشخص شود.
گام چهارم: نصب کتابخانه مورد نیاز
گام پنجم: آپلود کد در آردوینو
کد زیر برای تست الایدیهاست و به این صورت عمل میکند که تک تک پیکسلها را به ترتیب روشن و سپس همه را با هم خاموش میکند. کد زیر را در آردوینو کپی و اجرا کنید.
// Electropeak . CafeRobot
// Ali Akbar Hosseini
// Adafruit NeoPixel library simple test
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN 6 // On Trinket or Gemma, suggest changing this to 1
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 16 // Popular NeoPixel ring size
// When setting up the NeoPixel library, we tell it how many pixels,
// and which pin to use to send signals. Note that for older NeoPixel
// strips you might need to change the third parameter -- see the
// strandtest example for more information on possible values.
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels
void setup() {
// These lines specifically support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
}
void loop() {
pixels.clear(); // Set all pixel colors to 'off'
// The first NeoPixel in a strand is #0, second is 1, all the way up
// to the count of pixels minus one.
delay(500);
for(int i=0; i<NUMPIXELS; i++) { // For each pixel...
// pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
// Here we're using a moderately bright green color:
pixels.setPixelColor(i, pixels.Color(150, 150, 0));
pixels.show(); // Send the updated pixel colors to the hardware.
delay(DELAYVAL); // Pause before next pass through loop
}
}
توضیح مختصر کد بالا:
با دستور زیر، تعداد الایدی های متصل به هم مشخص میشود. به عنوان مثال در اینجا عدد 16 تعریف شده است.
#define NUMPIXELS 16
با استفاده از دستور pixel.Color(150, 150, 0)
تمام الایدی ها خاموش میشوند.
با خط اول دستور زیر، ابتدا پیکسل شماره i به رنگ pixels.Color(150, 150, 0) نوشته شده، و با خط دوم، این تغییرات اعمال میشود.
pixels.setPixelColor(i, pixels.Color(150, 150, 0));
pixels.show();
ساختار pixels.Color(R, G, B)
مقدار رنگهای قرمز، سبز و آبی را دریافت میکند که هر کدام اعدادی از بازه 0 تا 255 هستند. به عنوان مثال pixels.Color(255, 0, 0)
رنگ قرمز و pixels.Color(0, 255, 0)
رنگ سبز را به صورت کامل روشن میکند. با ترکیب این اعداد به میزان دلخواه میتوان 256*256*256 رنگ مختلف را در یک الایدی ایجاد کرد.
راه اندازی چندین ماژول WS2812 به صورت متوالی
متصل کردن چند ماژول که هر کدام شامل چندین الایدی هستند همانند اتصال الایدی های تکی است و هیچ تفاوتی ندارد. آخرین پیکسل هر ماژول اطلاعات را به اولین پیکسل ماژول بعدی ارسال میکند و این روند ادامه مییابد تا آخرین پیکسل. حتی میتوان براحتی ماژولهایی با تعداد متفاوت پیکسل را نیز به هم متصل کرد. آردوینو، همه را با هم به چشم یک رشته پیکسل متوالی میبیند.
سیم بندی

در مدار بالا، مانند مدار قبلی، سیم دیتا (سیم زرد) به پایه IN ماژول وارد و از پایه OUT خارج شده و به پایه IN ماژول بعدی میرود … و به همین ترتیب برای ماژولهای بعدی.
تعداد الایدی های ما در این حالت 32 تاست، یعنی جریان مورد نیاز تا 32*60=1920mA افزایش می یابد. پس به یک منبع تغذیه با خروجی حداقل 2 آمپر نیاز داریم. (توجه شود که عدد 1920 میلیآمپر برای زمانیست که همه 32 الای دی بهصورت کامل روشن باشند).
کد
پس از بستن مدار، کد زیر را در آردوینو کپی و اجرا کنید.
// Electropeak . CafeRobot
// Ali Akbar Hosseini
// Adafruit NeoPixel library RGBtest
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN 6
// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 32
// NeoPixel brightness, 0 (min) to 255 (max)
#define BRIGHTNESS 50 // Set BRIGHTNESS to about 1/5 (max = 255)
// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
void setup() {
// These lines specifically support the Adafruit Trinket 5V 16 MHz.
// Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
// END of Trinket-specific code.
strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show(); // Turn OFF all pixels ASAP
strip.setBrightness(BRIGHTNESS);
}
void loop() {
// Fill along the length of the strip in various colors...
colorWipe(strip.Color(255, 0, 0) , 50); // Red
colorWipe(strip.Color( 0, 255, 0) , 50); // Green
colorWipe(strip.Color( 0, 0, 255) , 50); // Blue
colorWipe(strip.Color( 0, 0, 0, 255), 50); // True white (not RGB white)
whiteOverRainbow(75, 5);
pulseWhite(5);
rainbowFade2White(3, 3, 1);
}
// Fill strip pixels one after another with a color. Strip is NOT cleared
// first; anything there will be covered pixel by pixel. Pass in color
// (as a single 'packed' 32-bit value, which you can get by calling
// strip.Color(red, green, blue) as shown in the loop() function above),
// and a delay time (in milliseconds) between pixels.
void colorWipe(uint32_t color, int wait) {
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
delay(wait); // Pause for a moment
}
}
void whiteOverRainbow(int whiteSpeed, int whiteLength) {
if(whiteLength >= strip.numPixels()) whiteLength = strip.numPixels() - 1;
int head = whiteLength - 1;
int tail = 0;
int loops = 3;
int loopNum = 0;
uint32_t lastTime = millis();
uint32_t firstPixelHue = 0;
for(;;) { // Repeat forever (or until a 'break' or 'return')
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
if(((i >= tail) && (i <= head)) || // If between head & tail...
((tail > head) && ((i >= tail) || (i <= head)))) {
strip.setPixelColor(i, strip.Color(0, 0, 0, 255)); // Set white
} else { // else set rainbow
int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
}
}
strip.show(); // Update strip with new contents
// There's no delay here, it just runs full-tilt until the timer and
// counter combination below runs out.
firstPixelHue += 40; // Advance just a little along the color wheel
if((millis() - lastTime) > whiteSpeed) { // Time to update head/tail?
if(++head >= strip.numPixels()) { // Advance head, wrap around
head = 0;
if(++loopNum >= loops) return;
}
if(++tail >= strip.numPixels()) { // Advance tail, wrap around
tail = 0;
}
lastTime = millis(); // Save time of last movement
}
}
}
void pulseWhite(uint8_t wait) {
for(int j=0; j<256; j++) { // Ramp up from 0 to 255
// Fill entire strip with white at gamma-corrected brightness level 'j':
strip.fill(strip.Color(0, 0, 0, strip.gamma8(j)));
strip.show();
delay(wait);
}
for(int j=255; j>=0; j--) { // Ramp down from 255 to 0
strip.fill(strip.Color(0, 0, 0, strip.gamma8(j)));
strip.show();
delay(wait);
}
}
void rainbowFade2White(int wait, int rainbowLoops, int whiteLoops) {
int fadeVal=0, fadeMax=100;
// Hue of first pixel runs 'rainbowLoops' complete loops through the color
// wheel. Color wheel has a range of 65536 but it's OK if we roll over, so
// just count from 0 to rainbowLoops*65536, using steps of 256 so we
// advance around the wheel at a decent clip.
for(uint32_t firstPixelHue = 0; firstPixelHue < rainbowLoops*65536;
firstPixelHue += 256) {
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
// Offset pixel hue by an amount to make one full revolution of the
// color wheel (range of 65536) along the length of the strip
// (strip.numPixels() steps):
uint32_t pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
// strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
// optionally add saturation and value (brightness) (each 0 to 255).
// Here we're using just the three-argument variant, though the
// second value (saturation) is a constant 255.
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue, 255,
255 * fadeVal / fadeMax)));
}
strip.show();
delay(wait);
if(firstPixelHue < 65536) { // First loop,
if(fadeVal < fadeMax) fadeVal++; // fade in
} else if(firstPixelHue >= ((rainbowLoops-1) * 65536)) { // Last loop,
if(fadeVal > 0) fadeVal--; // fade out
} else {
fadeVal = fadeMax; // Interim loop, make sure fade is at max
}
}
for(int k=0; k<whiteLoops; k++) {
for(int j=0; j<256; j++) { // Ramp up 0 to 255
// Fill entire strip with white at gamma-corrected brightness level 'j':
strip.fill(strip.Color(0, 0, 0, strip.gamma8(j)));
strip.show();
}
delay(1000); // Pause 1 second
for(int j=255; j>=0; j--) { // Ramp down 255 to 0
strip.fill(strip.Color(0, 0, 0, strip.gamma8(j)));
strip.show();
}
}
delay(500);
}
کد بالا سناریوهای رنگی مختلف را روی الایدی ها پیاده سازی میکند.
تعداد پیکسل ها (الایدی ها) در خط زیر مشخص میشود. برای ما 32 تاست. فرقی نمیکند اگر از ماژولهایی با تعداد متفاوت الایدی استفاده کنید. کافیست مجموع تعداد الایدی ها را در خط زیر درست وارد کنید تا تک تک الایدی ها تست شوند.
#define LED_COUNT 32
فیلم زیر، خروجی کد بالا با یک ماژول 16 تایی است.
مثال 1: راه اندازی نئوپیکسل WS2812 با آردوینو
سیم بندی
کد
/*
NeoPixel LEDs
modified on 7 May 2019
by Saeed Hosseini @ Electropeak
**This code is based on Adafruit NeoPixel library Example**
Home<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="“Home” — Electropeak" src="https://electropeak.com/learn/embed/#?secret=nG32uunlUG" data-secret="nG32uunlUG" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
*/
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN 6
#define NUMPIXELS 7
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels
void setup() {
pixels.begin();
}
void loop() {
pixels.clear();
pixels.setBrightness(10);
pixels.setPixelColor(0, pixels.Color(255, 255, 255));
pixels.setPixelColor(1, pixels.Color(255, 0, 0));
pixels.setPixelColor(2, pixels.Color(0, 255, 0));
pixels.setPixelColor(3, pixels.Color(0, 0, 255));
pixels.setPixelColor(4, pixels.Color(255, 0, 255));
pixels.setPixelColor(5, pixels.Color(255, 255, 0));
pixels.setPixelColor(6, pixels.Color(0, 255, 255));
pixels.show();
}
توضیحات کد
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
در ابتدا تابع فوق تعداد LEDها و پایه آردوینو را مشخص می کند.
pixels.begin();
پیکربندی های اولیه را انجام می دهد،
pixel.setBrightness(b);
شدت روشنایی را تعیین می کند (1 حداقل و 255 حداکثر)
pixels.setPixelColor(Wich LED,Wich color(Red,Green,Blue));
با مشخص کردن شماره LED (از 0 تا NUMPIXELS-1)، رنگ آن را با سیستم RGB تعیین می کند،
pixels.show();
مقادیر اعمال شده را به نمایش در می آورد.
مثال 2: حالت چشمک زن نئوپیکسل WS2812 با آردوینو
/*
NeoPixel LEDs
modified on 7 May 2019
by Saeed Hosseini @ Electropeak
Home<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="“Home” — Electropeak" src="https://electropeak.com/learn/embed/#?secret=nG32uunlUG" data-secret="nG32uunlUG" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
*/
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN 6
#define NUMPIXELS 7
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void NeoBlink(int num, int wait)
{
for (int i = 0; i < num; i++)
{
pixels.setPixelColor(i, 35, 35, 35);
}
pixels.show();
delay(wait);
for (int j = 0; j < num; j++)
{
pixels.setPixelColor(j, 0, 255, 0);
}
pixels.show();
delay(wait);
}
void setup()
{
pixels.begin();
pixels.setBrightness(50);
}
void loop()
{
NeoBlink(7, 500);
}
مثال 3: حالت محو شدن (Fade) نئوپیکسل WS2812 با آردوینو
/*
/*
NeoPixel LEDs
modified on 7 May 2019
by Saeed Hosseini @ Electropeak
Home<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="“Home” — Electropeak" src="https://electropeak.com/learn/embed/#?secret=nG32uunlUG" data-secret="nG32uunlUG" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
*/
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN 6
#define NUMPIXELS 7
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels
void NeoFade(int FadeSpeed)
{
int fspeed;
for (int i = 0; i < NUMPIXELS; i++) { pixels.setPixelColor(i, 165, 242, 243); } for (int j = 255; j > 0; j=j-2)
{
pixels.setBrightness(j);
pixels.show();
delay(FadeSpeed);
}
}
void setup() {
pixels.begin();
}
void loop() {
NeoFade(100);
}
مثال 4: انتخاب تصادفی نئوپیکسل WS2812 با آردوینو
در این مثال با استفاده از تابع (random(num1,num2 عددی تصادفی در بازه num1 تا num2 برای رنگ و LED تولید کرده و آن را نمایش می دهیم.
/*
NeoPixel LEDs
modified on 7 May 2019
by Saeed Hosseini @ Electropeak
Home<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="“Home” — Electropeak" src="https://electropeak.com/learn/embed/#?secret=nG32uunlUG" data-secret="nG32uunlUG" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
*/
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN 6
#define NUMPIXELS 7
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500 // Time (in milliseconds) to pause between pixels
void setup() {
pixels.begin();
}
void loop() {
pixels.clear();
pixels.setPixelColor(random(0, 7), random(0, 255), random(0, 255), random(0, 255));
pixels.show();
delay(500);
}
مثال 5: حالت رنگین کمان نئوپیکسل WS2812 با آردوینو
یکی از ابزارهای جذاب تحت وب برای ساخت افکت روی ال ای دی های WS2812 یا نئوپیکسل ها Neopixel Effects Generator، می باشد که با استفاده از آن می توانید تعداد LED ها و پایه آردوینو را تعیین کنید و بعد از ساخت افکت و تنظیمات مدنظرتان با کلیک برروی generate Arduino code کد آردینو را تولید کرده و در IDE کپی کنید. براای این کار طبق مراحل زیر پیش بروید:
- بعد از ورود به سایت روی Add led strip کلیک کنید.
2. روی رشته ال ای دی اضافه شده کلیک کرده و تعداد LED و پایه آردوینو را مشخص کنید.
3. در قسمت loop روی Add Effect کلیک کرده و افکت دلخواه خود را انتخاب کنید.
/*
This code is generated by:
https://adrianotiger.github.io/NeoPixel-Effect-Generator/
*/
#include <Adafruit_NeoPixel.h>
class Strip
{
public:
uint8_t effect;
uint8_t effects;
uint16_t effStep;
unsigned long effStart;
Adafruit_NeoPixel strip;
Strip(uint16_t leds, uint8_t pin, uint8_t toteffects) : strip(leds, pin, NEO_GRB + NEO_KHZ800) {
effect = -1;
effects = toteffects;
Reset();
}
void Reset(){
effStep = 0;
effect = (effect + 1) % effects;
effStart = millis();
}
};
struct Loop
{
uint8_t currentChild;
uint8_t childs;
bool timeBased;
uint16_t cycles;
uint16_t currentTime;
Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;}
};
Strip strip_0(7, 6, 7 );
struct Loop strip0loop0(1, false, 1);
//[GLOBAL_VARIABLES]
void setup() {
//Your setup here:
strip_0.strip.begin();
}
void loop() {
//Your code here:
strips_loop();
}
void strips_loop() {
if(strip0_loop0() & 0x01)
strip_0.strip.show();
}
uint8_t strip0_loop0() {
uint8_t ret = 0x00;
switch(strip0loop0.currentChild) {
case 0:
ret = strip0_loop0_eff0();break;
}
if(ret & 0x02) {
ret &= 0xfd;
if(strip0loop0.currentChild + 1 >= strip0loop0.childs) {
strip0loop0.currentChild = 0;
if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;}
}
else {
strip0loop0.currentChild++;
}
};
return ret;
}
uint8_t strip0_loop0_eff0() {
// Strip ID: 0 - Effect: Rainbow - LEDS: 7
// Steps: 8 - Delay: 87
// Colors: 7 (255.0.0, 0.255.0, 0.0.255, 255.157.0, 255.0.255, 0.255.255, 255.255.255, )
// Options: toLeft=true,
if(millis() - strip_0.effStart < 87 * (strip_0.effStep)) return 0x00;
float factor1, factor2;
uint16_t ind;
for(uint16_t j=0;j<7;j++) { ind = strip_0.effStep + j * 1.1428571428571428; switch((int)((ind % 8) / 1.1428571428571428)) { case 0: factor1 = 1.0 - ((float)(ind % 8 - 0 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 0) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2); break; case 1: factor1 = 1.0 - ((float)(ind % 8 - 1 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 1.1428571428571428) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2); break; case 2: factor1 = 1.0 - ((float)(ind % 8 - 2 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 2.2857142857142856) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 157 * factor2, 255 * factor1 + 0 * factor2); break; case 3: factor1 = 1.0 - ((float)(ind % 8 - 3 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 3.4285714285714284) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 157 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2); break; case 4: factor1 = 1.0 - ((float)(ind % 8 - 4 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 4.571428571428571) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2, 255 * factor1 + 255 * factor2); break; case 5: factor1 = 1.0 - ((float)(ind % 8 - 5 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 5.7142857142857135) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 255 * factor1 + 255 * factor2, 255 * factor1 + 255 * factor2); break; case 6: factor1 = 1.0 - ((float)(ind % 8 - 6 * 1.1428571428571428) / 1.1428571428571428); factor2 = (float)((int)(ind - 6.857142857142857) % 8) / 1.1428571428571428; strip_0.strip.setPixelColor(j, 255 * factor1 + 255 * factor2, 255 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2); break; } } if(strip_0.effStep >= 8) {strip_0.Reset(); return 0x03; }
else strip_0.effStep++;
return 0x01;
}
یک گام جلوتر
- سعی کنید افکت های دیگری را نیز روی ال ای دی های WS2812 خود امتحان کنید.
- سعی کنید ال ای دی WS2812 خود را بصورت بیسیم (وایفای، بلوتوث و …) کنترل کنید.
Comments (7)
خیلی مفید و عالی
سپاس از لطفتون
سلام میشه این نوع رو با آهنگ هماهنگ کرد یا با رنگ های روی صفحه نمایش
اگه میشه جوابشو ایمیل بزنی ممنون میشم
سلام.
بله امکانش هست. برای هماهنگ کردن با آهنگ کافیه که زمان تاخیر بین تغییر هر رنگ (delay) رو به درستی تنظیم کنید. برای هماهنگ کردن با رنگهای روی صفحه نمایشگر هم میشه با سنسور تشخیص رنگ این کار را انجام داد. میتونید برای اطلاعات بیشتر از آموزشهای زیر هم کمک بگیرید:
“https://thecaferobot.com/learn/interfacing-dy-sv17f-audio-mp3-player-module-with-arduino/”
“https://thecaferobot.com/learn/tcs230-color-sensor-w-arduino/” و “https://thecaferobot.com/learn/interfacing-tcs34725-color-sensor-with-arduino/”
سلام میخواستم ازتون خواهش کنم آموزش کنترل نئو پیکسل با گوشی رو هم بزارید با بلوتوث
سلام.
در رابطه با کنترل کردن نئوپیکسل با گوشی یک آموزش دیگر هم در سایت هست. این آموزش در رابطه با کنترل نئوپیکسل ها با کمک wifi هست و با یادگیری این آموزش میتونید به نحوی که دلخواهتون هست اصلاحش کنید. این آموزش رو میتونید تو این لینک مشاهده کنید.
“https://thecaferobot.com/learn/ws2812-rgb-led-control-with-arduino/”
سلام لطفا یک آموزش کامل برای ساخت رقص نور و افکت با توجه به صدای محیط یا در کل صدایی که شنیده میشود که بر اساس شدت صدا هم میزان روشنایی تغییر کند هم افکت و تغیرات در روشنایی پیکسل ها هماهنگ با صدا باشد