آموزش جامع استفاده از LEDهای آدرس پذیر WS2812 (نئوپیکسل) با آردوینو

فهرست مطالب

مقدمه

کدام ویژگی، ال‌ای‌دی‌های 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 Pinout

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

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

قطعات مورد نیاز

Arduino UNO R3 × 1
WS2812 LED × 1
سیم جامپر × 1
مقاومت 470اهم × 1
منبع تغذیه 5 ولت 1 آمپر × 1

نرم افزارهای مورد نیاز

Arduino IDE

راه اندازی ماژول WS2812 LED با آردوینو

همانطور که گفته شد راه‌اندازی تعداد زیادی از ال‌ای‌دی­ ها تنها با یک خط دیتا امکان­پذیر بوده و اطلاعات از یک بلوک ال‌ای‌دی به بلوک دیگر منتقل می‌شود.

گام اول: نحوه عملکرد آردوینو با ماژول WS2812

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

گام دوم: تغذیه مناسب

شاید اولین قدم در راه‌اندازی هر سیستمی، تهیه منبع تغذیه مناسب باشد.

ولتاژ مناسب راه‌‌اندازی این ال‌ای‌دی‌ها همان 5 ولت است.

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

پس یک منبع تغذیه 5 ولت 1 آمپر برای راه‌اندازی 16 عدد از این ال‌ای‌دی‌ها کافیست.

گام سوم: سیم بندی WS2812 با آردوینو

مدار را مطابق شکل زیر ببندید.

WS2812-Interface Circuit

 یک مقاومت 300 تا 500 اهمی باید به ابتدای خط دیتا افزوده شود تا جریان­ کشی ناخواسته‌ای اتفاق نیفتد. همین یک مقاومت هم برای کل ماژول‌ها کافیست.

خط دیتا در پروژه ما به پایه دیجیتال شماره 6 آردوینو متصل شده است. این پین قابل تغییر است. می‌توانید از هر پین دیجیتال دلخواه استفاده کنید. فقط توجه داشته باشید که این پین در کد برنامه هم باید مشخص شود.

گام چهارم: نصب کتابخانه مورد نیاز

کتابخانه مورد نیاز برای این ماژول Adafruit_NeoPixel است. فایل زیپ این کتابخانه را می‌توانید از این لینک دانلود کنید.

اگر برای نصب کتابخانه به راهنمایی بیشتری نیاز دارید روی این لینک کلیک کنید.

گام پنجم: آپلود کد در آردوینو

کد زیر برای تست ال‌ای‌دی‌هاست و به این صورت عمل می‌کند که تک تک پیکسل‌ها را به ترتیب روشن و سپس همه را با هم خاموش می‌کند. کد زیر را در آردوینو کپی و اجرا کنید.


// 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 به صورت متوالی

متصل کردن چند ماژول که هر کدام شامل چندین ال‌ای‌دی هستند همانند اتصال ال‌ای‌دی های تکی است و هیچ تفاوتی ندارد. آخرین پیکسل هر ماژول اطلاعات را به اولین پیکسل ماژول بعدی ارسال می‌کند و این روند ادامه می‌یابد تا آخرین پیکسل. حتی می‌توان براحتی ماژول‌هایی با تعداد متفاوت پیکسل را نیز به هم متصل کرد. آردوینو، همه را با هم به چشم یک رشته پیکسل متوالی می‌بیند.

سیم بندی

WS2812 Cascade circuit

در مدار بالا، مانند مدار قبلی، سیم دیتا (سیم زرد) به پایه 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 با آردوینو

سیم بندی

در این مثال با استفاده از آردوینو UNO نئوپیکسل ها را روشن کرده و رنگ و شدت نور هر یک را جداگانه کنترل می کنیم. برای راه اندازی نئوپیکسل با آردوینو از کتابخانه Adafruit NeoPixel استفاده کنید.

کد

/* 
  NeoPixel LEDs

  modified on 7 May 2019
  by Saeed Hosseini @ Electropeak
**This code is based on Adafruit NeoPixel library Example**
  
Home
*/ #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 با آردوینو

در این مثال نئوپیکسل ها را با حالت چشمک زن راه اندازی می کنیم. برای ساخت چشمک زن همه LED ها باید همزمان روشن و خاموش شوند، در حالت روشن ال ای دی ها می توانند رنگ های متفاوت داشته باشند.
/* 
  NeoPixel LEDs

  modified on 7 May 2019
  by Saeed Hosseini @ Electropeak
  
Home
*/ #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
*/ #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
*/ #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 کپی کنید. براای این کار طبق مراحل زیر پیش بروید:

  1. بعد از ورود به سایت روی Add led strip کلیک کنید.

2. روی رشته ال ای دی اضافه شده کلیک کرده و تعداد LED و پایه آردوینو را مشخص کنید.

3. در قسمت loop روی Add Effect کلیک کرده و افکت دلخواه خود را انتخاب کنید.

4. در بخش Animation و Color تنظیمات دلخواه خود را اعمال کنید.
5. در آخر با کلیک برروی generate Arduino code کد را تولید کرده و در Arduino IDE کپی کنید.
/* 

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 (6)

  • یاسین رضایی Reply

    خیلی مفید و عالی

    نوامبر 3, 2019 at 11:54 ب.ظ
    • سعید حسینی Reply

      سپاس از لطفتون

      دسامبر 18, 2019 at 4:56 ب.ظ
  • محمد Reply

    سلام میشه این نوع رو با آهنگ هماهنگ کرد یا با رنگ های روی صفحه نمایش
    اگه میشه جوابشو ایمیل بزنی ممنون میشم

    آوریل 15, 2021 at 10:33 ب.ظ
    • مهران ملکی Reply

      سلام.
      بله امکانش هست. برای هماهنگ کردن با آهنگ کافیه که زمان تاخیر بین تغییر هر رنگ (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/”

      آوریل 17, 2021 at 10:23 ق.ظ
  • امیرحسین Reply

    سلام میخواستم ازتون خواهش کنم آموزش کنترل نئو پیکسل با گوشی رو هم بزارید با بلوتوث

    آوریل 27, 2021 at 8:08 ب.ظ
    • مهران ملکی Reply

      سلام.
      در رابطه با کنترل کردن نئوپیکسل با گوشی یک آموزش دیگر هم در سایت هست. این آموزش در رابطه با کنترل نئوپیکسل ها با کمک wifi هست و با یادگیری این آموزش میتونید به نحوی که دلخواهتون هست اصلاحش کنید. این آموزش رو میتونید تو این لینک مشاهده کنید.
      “https://thecaferobot.com/learn/ws2812-rgb-led-control-with-arduino/”

      می 1, 2021 at 9:15 ق.ظ

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.