آردوینو - آموزش آردوینو-Arduinoتازه هاهمه ی مطالب

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

اطلاعاتی در مورد نحوه برنامه ریزی و سیگنال دهی به WS2812

در این بخش به بررسی روش سیگنال دهی این آی سی خواهیم پرداخت. در ابتدا نیز لازم به ذکر است که با توجه به اینکه برای استفاده از این آی سی از کتابخانه های آماده بهره خواهیم گرفت لذا درک عمیق این مباحث ضروری نیست و صرفا جهت آشنایی با این ساختار مطرح می شود.
همان گونه که گفته شد برای اتصال این آی سی ها و تشکیل یک زنجیره باید دیتا از پایه ورودی اولین آی سی وارد و از پایه خروجی اولین آی سی به بعدی تا انتها اتصال یابد. به تصویر زیر توجه نمائید:ws2812

 

برای کنترل هر آی سی از 24 بیت استفاده می شود که 8 بیت برای هر رنگ قرمز، سبز و آبی استفاده می شود که در واقع امکان 256 حالت نوری(Grayscale) را ممکن می سازد. تصویر زیر ترتیب ارسال این سیگنال را نمایش می دهد:

1409986446_data_sequence-1024x56

این سیگنال ها باید به صورت پشت سر هم و به صورت سریال ارسال شود یعنی با فرض سه پیکسل به صورت پشت سر هم، یک بسته 24 بیتی به ازای هر پیکسل ارسال می شود. هر پیکسل اولین 24 بیت دریافتی را به خود اختصاص داده و باقی بیت های دریافتی را به پیکسل های بعدی منتقل می نماید. این روند تا آخرین پیکسل ادامه می یابد. با یک سیگنال ریست نیز کل آی سی های زنجیره خاموش می شود. در تصویر زیر شیوه اجرایی این فرآیند مشاهده می شود:

ws28121

با توجه به اینکه برای ارتباط و انتقال اطلاعات از یک خط دیتا(سریال) استفاده شده است لذا از روش خاصی برای تعیین صفر و یک منطقی و همچنین سیگنال ریست استفاده شده است. در این حالت برای نمایش صفر و یک منطقی از زمان بندی های خاص بهره گرفته شده است. یعنی با ست و ریست شدن خط دیتا به زمان معین سیگنال معرف صفر، یک و ریست خواهد بود.

 

همان گونه که قبلا نیز گفته شد این آی سی دارای دو مد کار1409986682_sequence_chartی 400 کیلو هرتز(Low Speed) و 800 کیلوهرتز (High Speed) می باشد. با توجه به اینکه زمان بندی های سیگنال با توجه به مد کاری تغییر می کند و همچنین سرعت بالاتر مد پر سرعت و متداول تر بودن این مد کاری، زمان بندی ها بر اساس آن قرار داده می شود: (لازم به ذکر است زمان بندی های مد 400 کیلو دو برابر جدول زیر است)

1409986682_table

روند ارسال سیگنال بدین صورت است که در ابتدا یک سیگنال ریست از طریق خط دیتا ارسال می شود. در این حالت حافظه کل چیپ ها پاک (Clear) می شود. بعد از این حالت سیگنال های ارتباطی با زمان بندی ها مناسب ارسال می گردد برای مثال با وجود دو آی سی پشت سر هم و به جهت رنگ سفید و سبز باید ابتدا 0xFFF (رنگ سفید) و سپس 0x0F0 (رنگ سبز خالص) به صورت پشت هم ارسال گردد.

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

  • برد آردوینو UNO
  • ماژول WS2812 – LED RGB

ترتیب پایه های ماژولWS2812 – LED RGB

ws2812b_pins

نحوه اتصال ماژول WS2812 – LED RGB به آردوینو

51f1a42fce395f8520000001

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

#include <Adafruit_NeoPixel.h>
#include "WS2812_Definitions.h"
#define PIN 4
#define LED_COUNT 5

// Create an instance of the Adafruit_NeoPixel class called "leds".
// That'll be what we refer to from here on...
Adafruit_NeoPixel leds = Adafruit_NeoPixel(LED_COUNT, PIN, NEO_GRB + NEO_KHZ800);

void setup()
{
  leds.begin();  // Call this to start up the LED strip.
  clearLEDs();   // This function, defined below, turns all LEDs off...
  leds.show();   // ...but the LEDs don't actually update until you call this.
}

void loop()
{
  // Ride the Rainbow Road
  for (int i=0; i<LED_COUNT*10; i++)
  {
    rainbow(i);
    delay(100);  // Delay between rainbow slides
  }
  
  // Indigo cylon
  // Do a cylon (larson scanner) cycle 10 times
  for (int i=0; i<10; i++)
  {
    // cylon function: first param is color, second is time (in ms) between cycles
    cylon(INDIGO, 500);  // Indigo cylon eye!
  }
  
  // A light shower of spring green rain
  // This will run the cascade from top->bottom 20 times
  for (int i=0; i<20; i++)
  {
    // First parameter is the color, second is direction, third is ms between falls
    cascade(MEDIUMSPRINGGREEN, TOP_DOWN, 100); 
  }
}

// Implements a little larson "cylon" sanner.
// This'll run one full cycle, down one way and back the other
void cylon(unsigned long color, byte wait)
{
  // weight determines how much lighter the outer "eye" colors are
  const byte weight = 4;  
  // It'll be easier to decrement each of these colors individually
  // so we'll split them out of the 24-bit color value
  byte red = (color & 0xFF0000) >> 16;
  byte green = (color & 0x00FF00) >> 8;
  byte blue = (color & 0x0000FF);
  
  // Start at closest LED, and move to the outside
  for (int i=0; i<=LED_COUNT-1; i++)
  {
    clearLEDs();
    leds.setPixelColor(i, red, green, blue);  // Set the bright middle eye
    // Now set two eyes to each side to get progressively dimmer
    for (int j=1; j<3; j++)
    {
      if (i-j >= 0)
        leds.setPixelColor(i-j, red/(weight*j), green/(weight*j), blue/(weight*j));
      if (i-j <= LED_COUNT)
        leds.setPixelColor(i+j, red/(weight*j), green/(weight*j), blue/(weight*j));
    }
    leds.show();  // Turn the LEDs on
    delay(wait);  // Delay for visibility
  }
  
  // Now we go back to where we came. Do the same thing.
  for (int i=LED_COUNT-2; i>=1; i--)
  {
    clearLEDs();
    leds.setPixelColor(i, red, green, blue);
    for (int j=1; j<3; j++)
    {
      if (i-j >= 0)
        leds.setPixelColor(i-j, red/(weight*j), green/(weight*j), blue/(weight*j));
      if (i-j <= LED_COUNT)
        leds.setPixelColor(i+j, red/(weight*j), green/(weight*j), blue/(weight*j));
      }
    
    leds.show();
    delay(wait);
  }
}

// Cascades a single direction. One time.
void cascade(unsigned long color, byte direction, byte wait)
{
  if (direction == TOP_DOWN)
  {
    for (int i=0; i<LED_COUNT; i++)
    {
      clearLEDs();  // Turn off all LEDs
      leds.setPixelColor(i, color);  // Set just this one
      leds.show();
      delay(wait);
    }
  }
  else
  {
    for (int i=LED_COUNT-1; i>=0; i--)
    {
      clearLEDs();
      leds.setPixelColor(i, color);
      leds.show();
      delay(wait);
    }
  }
}

// Sets all LEDs to off, but DOES NOT update the display;
// call leds.show() to actually turn them off after this.
void clearLEDs()
{
  for (int i=0; i<LED_COUNT; i++)
  {
    leds.setPixelColor(i, 0);
  }
}

// Prints a rainbow on the ENTIRE LED strip.
//  The rainbow begins at a specified position. 
// ROY G BIV!
void rainbow(byte startPosition) 
{
  // Need to scale our rainbow. We want a variety of colors, even if there
  // are just 10 or so pixels.
  int rainbowScale = 192 / LED_COUNT;
  
  // Next we setup each pixel with the right color
  for (int i=0; i<LED_COUNT; i++)
  {
    // There are 192 total colors we can get out of the rainbowOrder function.
    // It'll return a color between red->orange->green->...->violet for 0-191.
    leds.setPixelColor(i, rainbowOrder((rainbowScale * (i + startPosition)) % 192));
  }
  // Finally, actually turn the LEDs on:
  leds.show();
}

// Input a value 0 to 191 to get a color value.
// The colors are a transition red->yellow->green->aqua->blue->fuchsia->red...
//  Adapted from Wheel function in the Adafruit_NeoPixel library example sketch
uint32_t rainbowOrder(byte position) 
{
  // 6 total zones of color change:
  if (position < 31)  // Red -> Yellow (Red = FF, blue = 0, green goes 00-FF)
  {
    return leds.Color(0xFF, position * 8, 0);
  }
  else if (position < 63)  // Yellow -> Green (Green = FF, blue = 0, red goes FF->00)
  {
    position -= 31;
    return leds.Color(0xFF - position * 8, 0xFF, 0);
  }
  else if (position < 95)  // Green->Aqua (Green = FF, red = 0, blue goes 00->FF)
  {
    position -= 63;
    return leds.Color(0, 0xFF, position * 8);
  }
  else if (position < 127)  // Aqua->Blue (Blue = FF, red = 0, green goes FF->00)
  {
    position -= 95;
    return leds.Color(0, 0xFF - position * 8, 0xFF);
  }
  else if (position < 159)  // Blue->Fuchsia (Blue = FF, green = 0, red goes 00->FF)
  {
    position -= 127;
    return leds.Color(position * 8, 0, 0xFF);
  }
  else  //160 <position< 191   Fuchsia->Red (Red = FF, green = 0, blue goes FF->00)
  {
    position -= 159;
    return leds.Color(0xFF, 0x00, 0xFF - position * 8);
  }
}

منابع لازم برای راه اندازی ماژول

 

علی عزتی

علی عزتی هستم. رشته ی مهندسی برق الکترونیک رو خوندم. علاقه ی من به یادگیری و به اشتراک گذاشتن چیز هایی که یاد گرفتم. باعث شد تا الکترولب ایجاد بشه. علاقه ی زیادی به الکترونیک دارم. و دوست دارم چیزهای جدید یادبگیرم و بسازم ... :))

نوشته های مشابه

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

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.