回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【雕爷学编程】Arduino动手做(60)---WS2812直条8位模块3 中等

头像 驴友花雕 2023.07.24 13 1

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。

 

【Arduino】168种传感器模块系列实验(资料+代码+图形+仿真)
实验六十: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
 

03.jpg

知识点:WS2812B芯片

是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个5050LED灯珠相同,每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路,还包含有高精度的内部振荡器和12V高压可编程定电流控制部分,有效保证了像素点光的颜色高度一致。数据协议采用单线归零码的通讯方式,像素点在上电复位以后,DIN端接受从控制器传输过来的数据,首先送过来的24bit数据被第一个像素点提取后,送到像素点内部的数据锁存器,剩余的数据经过内部整形处理电路整形放大后通过DO端口开始转发输出给下一个级联的像素点,每经过一个像素点的传输,信号减少24bit。像素点采用自动整形转发技术,使得该像素点的级联个数不受信号传送的限制,仅仅受限信号传输速度要求。

 

0-.jpg

WS2812主要特点

1、智能反接保护,电源反接不会损坏IC。

2、IC控制电路与LED点光源公用一个电源。

3、控制电路与RGB芯片集成在一个5050封装的元器件中,构成一个完整的外控像素点。

4、内置信号整形电路,任何一个像素点收到信号后经过波形整形再输出,保证线路波形畸变不会累加。

5、内置上电复位和掉电复位电路。

6、每个像素点的三基色颜色可实现256级亮度显示,完成16777216种颜色的全真色彩显示,扫描频率不低于400Hz/s。

7、串行级联接口,能通过一根信号线完成数据的接收与解码。

8、任意两点传传输距离在不超过5米时无需增加任何电路。

9、当刷新速率30帧/秒时,级联数不小于1024点。

10、数据发送速度可达800Kbps。

11、光的颜色高度一致,性价比高。

 

07.jpg

  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验六十: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
  项目十二:标准的NeoPixel灯条循环测试

 Arduino实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验六十一: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
  项目十二:标准的NeoPixel灯条循环测试
*/

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 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)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup() {
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code

  strip.begin();
  strip.setBrightness(50);
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  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); // White RGBW
  // Send a theater pixel chase in...
  theaterChase(strip.Color(127, 127, 127), 50); // White
  theaterChase(strip.Color(127, 0, 0), 50); // Red
  theaterChase(strip.Color(0, 0, 127), 50); // Blue

  rainbow(20);
  rainbowCycle(20);
  theaterChaseRainbow(50);
}

// Fill the dots one after the other with a color
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);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
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);
  }
}

//Theatre-style crawling lights.
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 (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, c);  //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
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 (uint16_t 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 (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Arduino实验场景图

 

17.jpg

Adafruit_NeoPixel函数

一、初始化
1、包含头文件

 

#include <Adafruit_NeoPixel.h>

复制代码



2、针对AVR单片机的特殊设置

 

<div>#ifdef __AVR__</div><div> #include <avr/power.h> // Required for 16 MHz Adafruit Trinket</div><div>#endif</div><div>
 </div><div>// These lines are specifically to support the Adafruit Trinket 5V 16 MHz.</div><div>// Any other board, you can remove this part (but no harm leaving it):</div><div>
 </div><div>#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)</div><div>  clock_prescale_set(clock_div_1);</div><div>#endif</div>

复制代码



3、引脚及灯珠的数量定义

 

<div>// Which pin on the Arduino is connected to the NeoPixels?</div><div>#define PIN        6  // On Trinket or Gemma, suggest changing this to 1</div><div>
 </div><div>#define NUMPIXELS 3 // Popular NeoPixel ring size</div>

复制代码



4、定义strip函数

 

Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

复制代码



5、初始化strip函数

 

strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)

复制代码



6、输出函数
每次设置完后需要调用此函数进行输出,否则无现象

 

strip.show();

复制代码


 

二、颜色设置
1、将颜色的R、G、B设置为0

 

<p>strip.clear();</p><p></p>

复制代码


2、RGB设置函数

 

<p>static uint32_t Adafruit_NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b)</p><p>static uint32_t Adafruit_NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w)</p><p>static uint32_t Adafruit_CPlay_NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b)</p><p>static uint32_t Adafruit_CPlay_NeoPixel::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t w)</p>

复制代码

 

<p>void Adafruit_CPlay_NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b)</p><p>void Adafruit_CPlay_NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w)</p><p>void Adafruit_CPlay_NeoPixel::setPixelColor(uint16_t n, uint32_t c)</p><p>void Adafruit_CircuitPlayground::setPixelColor(uint8_t p, uint32_t c)</p><p>void Adafruit_CircuitPlayground::setPixelColor(uint8_t p, uint8_t r, uint8_t g, uint8_t b)</p><p>void Adafruit_NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b)</p><p>void Adafruit_NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w)</p><p>void Adafruit_NeoPixel::setPixelColor(uint16_t n, uint32_t c)</p>

复制代码


备注:n是引脚标号,从0开始。w是亮度,0~255

三、亮度设置

 

<p>void Adafruit_CPlay_NeoPixel::setBrightness(uint8_t b)</p><p>void Adafruit_CircuitPlayground::setBrightness(uint16_t b)</p><p>void Adafruit_NeoPixel::setBrightness(uint8_t b)</p>

复制代码


使用完这个函数之后需要调用show函数,才能输出
 

  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
 实验六十: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
 项目十三:使用FastLED库的简易流动变色

 实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验六十一: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
  项目十三:使用FastLED库的简易流动变色
*/

#include <FastLED.h>
#define LED_PIN     6
#define NUM_LEDS    8
CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
}

void loop() {
  for (int i = 0; i <= 7; i++) {
    leds[i] = CRGB ( 0, 0, 255);
    FastLED.show();
    delay(80);
  }
  for (int i = 7; i >= 0; i--) {
    leds[i] = CRGB ( 220, 0, 0);
    FastLED.show();
    delay(80);
  }
    for (int i = 0; i <= 7; i++) {
    leds[i] = CRGB ( 0, 230, 0);
    FastLED.show();
    delay(80);
  }
    for (int i = 7; i >= 0; i--) {
    leds[i] = CRGB ( 150, 50, 0);
    FastLED.show();
    delay(80);
  }
}

  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验六十: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
 项目十四:使用FastLED库的八种快速调色板

 实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验六十一: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
  项目十四:使用FastLED库的八种快速调色板
*/

#include <FastLED.h>

#define LED_PIN     5
#define NUM_LEDS    8
#define BRIGHTNESS  50
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

#define UPDATES_PER_SECOND 100

CRGBPalette16 currentPalette;
TBlendType    currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;


void setup() {
  delay( 3000 ); // power-up safety delay
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(  BRIGHTNESS );
  currentPalette = RainbowColors_p;
  currentBlending = LINEARBLEND;
}

void loop() {
  ChangePalettePeriodically();
  static uint8_t startIndex = 0;
  startIndex = startIndex + 1; /* motion speed */
  FillLEDsFromPaletteColors( startIndex);
  FastLED.show();
  FastLED.delay(1000 / UPDATES_PER_SECOND);
}

void FillLEDsFromPaletteColors( uint8_t colorIndex) {
  uint8_t brightness = 255;
  for ( int i = 0; i < NUM_LEDS; ++i) {
    leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
    colorIndex += 3;
  }
}

void ChangePalettePeriodically() {
  uint8_t secondHand = (millis() / 1000) % 60;
  static uint8_t lastSecond = 99;
  if ( lastSecond != secondHand) {
    lastSecond = secondHand;
    if ( secondHand ==  0)  {
      currentPalette = RainbowColors_p;
      currentBlending = LINEARBLEND;
    }
    if ( secondHand == 10)  {
      currentPalette = RainbowStripeColors_p;
      currentBlending = NOBLEND;
    }
    if ( secondHand == 15)  {
      currentPalette = RainbowStripeColors_p;
      currentBlending = LINEARBLEND;
    }
    if ( secondHand == 20)  {
      SetupPurpleAndGreenPalette();
      currentBlending = LINEARBLEND;
    }
    if ( secondHand == 25)  {
      SetupTotallyRandomPalette();
      currentBlending = LINEARBLEND;
    }
    if ( secondHand == 30)  {
      SetupBlackAndWhiteStripedPalette();
      currentBlending = NOBLEND;
    }
    if ( secondHand == 35)  {
      SetupBlackAndWhiteStripedPalette();
      currentBlending = LINEARBLEND;
    }
    if ( secondHand == 40)  {
      currentPalette = CloudColors_p;
      currentBlending = LINEARBLEND;
    }
    if ( secondHand == 45)  {
      currentPalette = PartyColors_p;
      currentBlending = LINEARBLEND;
    }
    if ( secondHand == 50)  {
      currentPalette = myRedWhiteBluePalette_p;
      currentBlending = NOBLEND;
    }
    if ( secondHand == 55)  {
      currentPalette = myRedWhiteBluePalette_p;
      currentBlending = LINEARBLEND;
    }
  }
}

// This function fills the palette with totally random colors.
void SetupTotallyRandomPalette() {
  for ( int i = 0; i < 16; ++i) {
    currentPalette[i] = CHSV( random8(), 255, random8());
  }
}

void SetupBlackAndWhiteStripedPalette() {
  // 'black out' all 16 palette entries...
  fill_solid( currentPalette, 16, CRGB::Black);
  // and set every fourth one to white.
  currentPalette[0] = CRGB::White;
  currentPalette[4] = CRGB::White;
  currentPalette[8] = CRGB::White;
  currentPalette[12] = CRGB::White;
}

// This function sets up a palette of purple and green stripes.
void SetupPurpleAndGreenPalette() {
  CRGB purple = CHSV( HUE_PURPLE, 255, 255);
  CRGB green  = CHSV( HUE_GREEN, 255, 255);
  CRGB black  = CRGB::Black;
  currentPalette = CRGBPalette16(
                     green,  green,  black,  black,
                     purple, purple, black,  black,
                     green,  green,  black,  black,
                     purple, purple, black,  black );
}

const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM =
{
  CRGB::Red,
  CRGB::Gray, // 'white' is too bright compared to red and blue
  CRGB::Blue,
  CRGB::Black,

  CRGB::Red,
  CRGB::Gray,
  CRGB::Blue,
  CRGB::Black,

  CRGB::Red,
  CRGB::Red,
  CRGB::Gray,
  CRGB::Gray,
  CRGB::Blue,
  CRGB::Blue,
  CRGB::Black,
  CRGB::Black
};

  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验六十: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
 项目十五:每个 LED 灯条的颜色校正设置,以及总输出'色温'的总控制

 实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验六十一: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
  项目十五:每个 LED 灯条的颜色校正设置,以及总输出'色温'的总控制
*/

#include <FastLED.h>
#define LED_PIN     5
// Information about the LED strip itself
#define NUM_LEDS    8
#define CHIPSET     WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
#define BRIGHTNESS  128

// FastLED v2.1 provides two color-management controls:
//   (1) color correction settings for each LED strip, and
//   (2) master control of the overall output 'color temperature' 
//
// THIS EXAMPLE demonstrates the second, "color temperature" control.
// It shows a simple rainbow animation first with one temperature profile,
// and a few seconds later, with a different temperature profile.
//
// The first pixel of the strip will show the color temperature.
//
// HELPFUL HINTS for "seeing" the effect in this demo:
// * Don't look directly at the LED pixels.  Shine the LEDs aganst
//   a white wall, table, or piece of paper, and look at the reflected light.
//
// * If you watch it for a bit, and then walk away, and then come back 
//   to it, you'll probably be able to "see" whether it's currently using
//   the 'redder' or the 'bluer' temperature profile, even not counting
//   the lowest 'indicator' pixel.
//
//
// FastLED provides these pre-conigured incandescent color profiles:
//     Candle, Tungsten40W, Tungsten100W, Halogen, CarbonArc,
//     HighNoonSun, DirectSunlight, OvercastSky, ClearBlueSky,
// FastLED provides these pre-configured gaseous-light color profiles:
//     WarmFluorescent, StandardFluorescent, CoolWhiteFluorescent,
//     FullSpectrumFluorescent, GrowLightFluorescent, BlackLightFluorescent,
//     MercuryVapor, SodiumVapor, MetalHalide, HighPressureSodium,
// FastLED also provides an "Uncorrected temperature" profile
//    UncorrectedTemperature;

#define TEMPERATURE_1 Tungsten100W
#define TEMPERATURE_2 OvercastSky

// How many seconds to show each temperature before switching
#define DISPLAYTIME 20
// How many seconds to show black between switches
#define BLACKTIME   3

void loop(){
  // draw a generic, no-name rainbow
  static uint8_t starthue = 0;
  fill_rainbow( leds + 5, NUM_LEDS - 5, --starthue, 20);

  // Choose which 'color temperature' profile to enable.
  uint8_t secs = (millis() / 1000) % (DISPLAYTIME * 2);
  if( secs < DISPLAYTIME) {
    FastLED.setTemperature( TEMPERATURE_1 ); // first temperature
    leds[0] = TEMPERATURE_1; // show indicator pixel
  } else {
    FastLED.setTemperature( TEMPERATURE_2 ); // second temperature
    leds[0] = TEMPERATURE_2; // show indicator pixel
  }

  // Black out the LEDs for a few secnds between color changes
  // to let the eyes and brains adjust
  if( (secs % DISPLAYTIME) < BLACKTIME) {
    memset8( leds, 0, NUM_LEDS * sizeof(CRGB));
  }
  
  FastLED.show();
  FastLED.delay(8);
}

void setup() {
  delay( 3000 ); // power-up safety delay
  // It's important to set the color correction for your LED strip here,
  // so that colors can be more accurately rendered through the 'temperature' profiles
  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalSMD5050 );
  FastLED.setBrightness( BRIGHTNESS );
}

  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
 实验六十: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
 项目十六:快速淡入淡出循环变色

 实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验六十一: 直条8位 WS2812B 5050 RGB LED内置全彩驱动彩灯模块
  项目十六:快速淡入淡出循环变色
*/

#include <FastLED.h>

// How many leds in your strip?
#define NUM_LEDS 8 

// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN.  For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806, define both DATA_PIN and CLOCK_PIN
#define DATA_PIN 5
//#define CLOCK_PIN 13

// Define the array of leds
CRGB leds[NUM_LEDS];

void setup() { 
        Serial.begin(57600);
        Serial.println("resetting");
        FastLED.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);
        FastLED.setBrightness(30);
}

void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } }

void loop() { 
        static uint8_t hue = 0;
        Serial.print("x");
        // First slide the led in one direction
        for(int i = 0; i < NUM_LEDS; i++) {
                // Set the i'th led to red 
                leds[i] = CHSV(hue++, 255, 255);
                // Show the leds
                FastLED.show(); 
                // now that we've shown the leds, reset the i'th led to black
                // leds[i] = CRGB::Black;
                fadeall();
                // Wait a little bit before we loop around and do it again
                delay(10);
        }
        Serial.print("x");

        // Now go in the other direction.  
        for(int i = (NUM_LEDS)-1; i >= 0; i--) {
                // Set the i'th led to red 
                leds[i] = CHSV(hue++, 255, 255);
                // Show the leds
                FastLED.show();
                // now that we've shown the leds, reset the i'th led to black
                // leds[i] = CRGB::Black;
                fadeall();
                // Wait a little bit before we loop around and do it again
                delay(10);
        }
}

Arduino实验场景图

 

10.jpg

评论

user-avatar
  • hacker_

    hacker_2023.08.10

    666

    0
    icon 他的勋章
      展开更多