【雕爷学编程】Arduino动手做(138)---64位WS2812点阵屏模块4
37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏
项目十九:骄傲2015动画,不断变化的彩虹
实验开源代码
/* 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程) 实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏 项目十九:骄傲2015动画,不断变化的彩虹 实验接线 Module UNO VCC —— 3.3V GND —— GND DI —— D6 */ #include "FastLED.h" // Pride2015 // Animated, ever-changing rainbows. // by Mark Kriegsman #if FASTLED_VERSION < 3001000 #error "Requires FastLED 3.1 or later; check github for latest code." #endif #define DATA_PIN 6 //#define CLK_PIN 4 #define LED_TYPE WS2811 #define COLOR_ORDER GRB #define NUM_LEDS 64 #define BRIGHTNESS 22 CRGB leds[NUM_LEDS]; void setup() { delay(3000); // 3 second delay for recovery // tell FastLED about the LED strip configuration FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS) .setCorrection(TypicalLEDStrip) .setDither(BRIGHTNESS < 255); // set master brightness control FastLED.setBrightness(BRIGHTNESS); } void loop() { pride(); FastLED.show(); } // This function draws rainbows with an ever-changing, // widely-varying set of parameters. void pride() { static uint16_t sPseudotime = 0; static uint16_t sLastMillis = 0; static uint16_t sHue16 = 0; uint8_t sat8 = beatsin88( 87, 220, 250); uint8_t brightdepth = beatsin88( 341, 96, 224); uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256)); uint8_t msmultiplier = beatsin88(147, 23, 60); uint16_t hue16 = sHue16;//gHue * 256; uint16_t hueinc16 = beatsin88(113, 1, 3000); uint16_t ms = millis(); uint16_t deltams = ms - sLastMillis ; sLastMillis = ms; sPseudotime += deltams * msmultiplier; sHue16 += deltams * beatsin88( 400, 5,9); uint16_t brightnesstheta16 = sPseudotime; for( uint16_t i = 0 ; i < NUM_LEDS; i++) { hue16 += hueinc16; uint8_t hue8 = hue16 / 256; brightnesstheta16 += brightnessthetainc16; uint16_t b16 = sin16( brightnesstheta16 ) + 32768; uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536; uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; bri8 += (255 - brightdepth); CRGB newcolor = CHSV( hue8, sat8, bri8); uint16_t pixelnumber = i; pixelnumber = (NUM_LEDS-1) - pixelnumber; nblend( leds[pixelnumber], newcolor, 64); } }
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏
项目二十:TwinkleFOX:淡入淡出的闪烁“假日”灯
实验开源代码
/* 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程) 实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏 项目二十:TwinkleFOX:淡入淡出的闪烁“假日”灯 实验接线 Module UNO VCC —— 3.3V GND —— GND DI —— D6 */ #include "FastLED.h" #define NUM_LEDS 64 #define LED_TYPE WS2811 #define COLOR_ORDER GRB #define DATA_PIN 6 //#define CLK_PIN 4 #define VOLTS 12 #define MAX_MA 4000 // TwinkleFOX: Twinkling 'holiday' lights that fade in and out. // Colors are chosen from a palette; a few palettes are provided. // // This December 2015 implementation improves on the December 2014 version // in several ways: // - smoother fading, compatible with any colors and any palettes // - easier control of twinkle speed and twinkle density // - supports an optional 'background color' // - takes even less RAM: zero RAM overhead per pixel // - illustrates a couple of interesting techniques (uh oh...) // // The idea behind this (new) implementation is that there's one // basic, repeating pattern that each pixel follows like a waveform: // The brightness rises from 0..255 and then falls back down to 0. // The brightness at any given point in time can be determined as // as a function of time, for example: // brightness = sine( time ); // a sine wave of brightness over time // // So the way this implementation works is that every pixel follows // the exact same wave function over time. In this particular case, // I chose a sawtooth triangle wave (triwave8) rather than a sine wave, // but the idea is the same: brightness = triwave8( time ). // // Of course, if all the pixels used the exact same wave form, and // if they all used the exact same 'clock' for their 'time base', all // the pixels would brighten and dim at once -- which does not look // like twinkling at all. // // So to achieve random-looking twinkling, each pixel is given a // slightly different 'clock' signal. Some of the clocks run faster, // some run slower, and each 'clock' also has a random offset from zero. // The net result is that the 'clocks' for all the pixels are always out // of sync from each other, producing a nice random distribution // of twinkles. // // The 'clock speed adjustment' and 'time offset' for each pixel // are generated randomly. One (normal) approach to implementing that // would be to randomly generate the clock parameters for each pixel // at startup, and store them in some arrays. However, that consumes // a great deal of precious RAM, and it turns out to be totally // unnessary! If the random number generate is 'seeded' with the // same starting value every time, it will generate the same sequence // of values every time. So the clock adjustment parameters for each // pixel are 'stored' in a pseudo-random number generator! The PRNG // is reset, and then the first numbers out of it are the clock // adjustment parameters for the first pixel, the second numbers out // of it are the parameters for the second pixel, and so on. // In this way, we can 'store' a stable sequence of thousands of // random clock adjustment parameters in literally two bytes of RAM. // // There's a little bit of fixed-point math involved in applying the // clock speed adjustments, which are expressed in eighths. Each pixel's // clock speed ranges from 8/8ths of the system clock (i.e. 1x) to // 23/8ths of the system clock (i.e. nearly 3x). // // On a basic Arduino Uno or Leonardo, this code can twinkle 300+ pixels // smoothly at over 50 updates per seond. // // -Mark Kriegsman, December 2015 CRGBArray<NUM_LEDS> leds; // Overall twinkle speed. // 0 (VERY slow) to 8 (VERY fast). // 4, 5, and 6 are recommended, default is 4. #define TWINKLE_SPEED 4 // Overall twinkle density. // 0 (NONE lit) to 8 (ALL lit at once). // Default is 5. #define TWINKLE_DENSITY 5 // How often to change color palettes. #define SECONDS_PER_PALETTE 30 // Also: toward the bottom of the file is an array // called "ActivePaletteList" which controls which color // palettes are used; you can add or remove color palettes // from there freely. // Background color for 'unlit' pixels // Can be set to CRGB::Black if desired. CRGB gBackgroundColor = CRGB::Black; // Example of dim incandescent fairy light background color // CRGB gBackgroundColor = CRGB(CRGB::FairyLight).nscale8_video(16); // If AUTO_SELECT_BACKGROUND_COLOR is set to 1, // then for any palette where the first two entries // are the same, a dimmed version of that color will // automatically be used as the background color. #define AUTO_SELECT_BACKGROUND_COLOR 0 // If COOL_LIKE_INCANDESCENT is set to 1, colors will // fade out slighted 'reddened', similar to how // incandescent bulbs change color as they get dim down. #define COOL_LIKE_INCANDESCENT 1 CRGBPalette16 gCurrentPalette; CRGBPalette16 gTargetPalette; void setup() { delay( 3000 ); //safety startup delay FastLED.setMaxPowerInVoltsAndMilliamps( VOLTS, MAX_MA); FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS) .setCorrection(TypicalLEDStrip); FastLED.setBrightness(23); chooseNextColorPalette(gTargetPalette); } void loop() { EVERY_N_SECONDS( SECONDS_PER_PALETTE ) { chooseNextColorPalette( gTargetPalette ); } EVERY_N_MILLISECONDS( 10 ) { nblendPaletteTowardPalette( gCurrentPalette, gTargetPalette, 12); } drawTwinkles( leds); FastLED.show(); } // This function loops over each pixel, calculates the // adjusted 'clock' that this pixel should use, and calls // "CalculateOneTwinkle" on each pixel. It then displays // either the twinkle color of the background color, // whichever is brighter. void drawTwinkles( CRGBSet& L) { // "PRNG16" is the pseudorandom number generator // It MUST be reset to the same starting value each time // this function is called, so that the sequence of 'random' // numbers that it generates is (paradoxically) stable. uint16_t PRNG16 = 11337; uint32_t clock32 = millis(); // Set up the background color, "bg". // if AUTO_SELECT_BACKGROUND_COLOR == 1, and the first two colors of // the current palette are identical, then a deeply faded version of // that color is used for the background color CRGB bg; if ( (AUTO_SELECT_BACKGROUND_COLOR == 1) && (gCurrentPalette[0] == gCurrentPalette[1] )) { bg = gCurrentPalette[0]; uint8_t bglight = bg.getAverageLight(); if ( bglight > 64) { bg.nscale8_video( 16); // very bright, so scale to 1/16th } else if ( bglight > 16) { bg.nscale8_video( 64); // not that bright, so scale to 1/4th } else { bg.nscale8_video( 86); // dim, scale to 1/3rd. } } else { bg = gBackgroundColor; // just use the explicitly defined background color } uint8_t backgroundBrightness = bg.getAverageLight(); for ( CRGB& pixel : L) { PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number uint16_t myclockoffset16 = PRNG16; // use that number as clock offset PRNG16 = (uint16_t)(PRNG16 * 2053) + 1384; // next 'random' number // use that number as clock speed adjustment factor (in 8ths, from 8/8ths to 23/8ths) uint8_t myspeedmultiplierQ5_3 = ((((PRNG16 & 0xFF) >> 4) + (PRNG16 & 0x0F)) & 0x0F) + 0x08; uint32_t myclock30 = (uint32_t)((clock32 * myspeedmultiplierQ5_3) >> 3) + myclockoffset16; uint8_t myunique8 = PRNG16 >> 8; // get 'salt' value for this pixel // We now have the adjusted 'clock' for this pixel, now we call // the function that computes what color the pixel should be based // on the "brightness = f( time )" idea. CRGB c = computeOneTwinkle( myclock30, myunique8); uint8_t cbright = c.getAverageLight(); int16_t deltabright = cbright - backgroundBrightness; if ( deltabright >= 32 || (!bg)) { // If the new pixel is significantly brighter than the background color, // use the new color. pixel = c; } else if ( deltabright > 0 ) { // If the new pixel is just slightly brighter than the background color, // mix a blend of the new color and the background color pixel = blend( bg, c, deltabright * 8); } else { // if the new pixel is not at all brighter than the background color, // just use the background color. pixel = bg; } } } // This function takes a time in pseudo-milliseconds, // figures out brightness = f( time ), and also hue = f( time ) // The 'low digits' of the millisecond time are used as // input to the brightness wave function. // The 'high digits' are used to select a color, so that the color // does not change over the course of the fade-in, fade-out // of one cycle of the brightness wave function. // The 'high digits' are also used to determine whether this pixel // should light at all during this cycle, based on the TWINKLE_DENSITY. CRGB computeOneTwinkle( uint32_t ms, uint8_t salt) { uint16_t ticks = ms >> (8 - TWINKLE_SPEED); uint8_t fastcycle8 = ticks; uint16_t slowcycle16 = (ticks >> 8) + salt; slowcycle16 += sin8( slowcycle16); slowcycle16 = (slowcycle16 * 2053) + 1384; uint8_t slowcycle8 = (slowcycle16 & 0xFF) + (slowcycle16 >> 8); uint8_t bright = 0; if ( ((slowcycle8 & 0x0E) / 2) < TWINKLE_DENSITY) { bright = attackDecayWave8( fastcycle8); } uint8_t hue = slowcycle8 - salt; CRGB c; if ( bright > 0) { c = ColorFromPalette( gCurrentPalette, hue, bright, NOBLEND); if ( COOL_LIKE_INCANDESCENT == 1 ) { coolLikeIncandescent( c, fastcycle8); } } else { c = CRGB::Black; } return c; } // This function is like 'triwave8', which produces a // symmetrical up-and-down triangle sawtooth waveform, except that this // function produces a triangle wave with a faster attack and a slower decay: // // / \ // / \ // / \ // / \ // uint8_t attackDecayWave8( uint8_t i) { if ( i < 86) { return i * 3; } else { i -= 86; return 255 - (i + (i / 2)); } } // This function takes a pixel, and if its in the 'fading down' // part of the cycle, it adjusts the color a little bit like the // way that incandescent bulbs fade toward 'red' as they dim. void coolLikeIncandescent( CRGB& c, uint8_t phase) { if ( phase < 128) return; uint8_t cooling = (phase - 128) >> 4; c.g = qsub8( c.g, cooling); c.b = qsub8( c.b, cooling * 2); } // A mostly red palette with green accents and white trim. // "CRGB::Gray" is used as white to keep the brightness more uniform. const TProgmemRGBPalette16 RedGreenWhite_p FL_PROGMEM = { CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray, CRGB::Green, CRGB::Green, CRGB::Green, CRGB::Green }; // A mostly (dark) green palette with red berries. #define Holly_Green 0x00580c #define Holly_Red 0xB00402 const TProgmemRGBPalette16 Holly_p FL_PROGMEM = { Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Green, Holly_Red }; // A red and white striped palette // "CRGB::Gray" is used as white to keep the brightness more uniform. const TProgmemRGBPalette16 RedWhite_p FL_PROGMEM = { CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Red, CRGB::Gray, CRGB::Gray, CRGB::Gray, CRGB::Gray }; // A mostly blue palette with white accents. // "CRGB::Gray" is used as white to keep the brightness more uniform. const TProgmemRGBPalette16 BlueWhite_p FL_PROGMEM = { CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Blue, CRGB::Gray, CRGB::Gray, CRGB::Gray }; // A pure "fairy light" palette with some brightness variations #define HALFFAIRY ((CRGB::FairyLight & 0xFEFEFE) / 2) #define QUARTERFAIRY ((CRGB::FairyLight & 0xFCFCFC) / 4) const TProgmemRGBPalette16 FairyLight_p FL_PROGMEM = { CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, HALFFAIRY, HALFFAIRY, CRGB::FairyLight, CRGB::FairyLight, QUARTERFAIRY, QUARTERFAIRY, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight, CRGB::FairyLight }; // A palette of soft snowflakes with the occasional bright one const TProgmemRGBPalette16 Snow_p FL_PROGMEM = { 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0x304048, 0xE0F0FF }; // A palette reminiscent of large 'old-school' C9-size tree lights // in the five classic colors: red, orange, green, blue, and white. #define C9_Red 0xB80400 #define C9_Orange 0x902C02 #define C9_Green 0x046002 #define C9_Blue 0x070758 #define C9_White 0x606820 const TProgmemRGBPalette16 RetroC9_p FL_PROGMEM = { C9_Red, C9_Orange, C9_Red, C9_Orange, C9_Orange, C9_Red, C9_Orange, C9_Red, C9_Green, C9_Green, C9_Green, C9_Green, C9_Blue, C9_Blue, C9_Blue, C9_White }; // A cold, icy pale blue palette #define Ice_Blue1 0x0C1040 #define Ice_Blue2 0x182080 #define Ice_Blue3 0x5080C0 const TProgmemRGBPalette16 Ice_p FL_PROGMEM = { Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue1, Ice_Blue2, Ice_Blue2, Ice_Blue2, Ice_Blue3 }; // Add or remove palette names from this list to control which color // palettes are used, and in what order. const TProgmemRGBPalette16* ActivePaletteList[] = { &RetroC9_p, &BlueWhite_p, &RainbowColors_p, &FairyLight_p, &RedGreenWhite_p, &PartyColors_p, &RedWhite_p, &Snow_p, &Holly_p, &Ice_p }; // Advance to the next color palette in the list (above). void chooseNextColorPalette( CRGBPalette16& pal) { const uint8_t numberOfPalettes = sizeof(ActivePaletteList) / sizeof(ActivePaletteList[0]); static uint8_t whichPalette = -1; whichPalette = addmod8( whichPalette, 1, numberOfPalettes); pal = *(ActivePaletteList[whichPalette]); }
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏
项目二十一:二维 XY 像素矩阵闪烁灯
实验开源代码
/* 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程) 实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏 项目二十一:二维 XY 像素矩阵闪烁灯 实验接线 Module UNO VCC —— 3.3V GND —— GND DI —— D6 */ #include <FastLED.h> #define LED_PIN 6 #define COLOR_ORDER GRB #define CHIPSET WS2811 #define BRIGHTNESS 26 // Helper functions for an two-dimensional XY matrix of pixels. // Simple 2-D demo code is included as well. // // XY(x,y) takes x and y coordinates and returns an LED index number, // for use like this: leds[ XY(x,y) ] == CRGB::Red; // No error checking is performed on the ranges of x and y. // // XYsafe(x,y) takes x and y coordinates and returns an LED index number, // for use like this: leds[ XYsafe(x,y) ] == CRGB::Red; // Error checking IS performed on the ranges of x and y, and an // index of "-1" is returned. Special instructions below // explain how to use this without having to do your own error // checking every time you use this function. // This is a slightly more advanced technique, and // it REQUIRES SPECIAL ADDITIONAL setup, described below. // Params for width and height const uint8_t kMatrixWidth = 16; const uint8_t kMatrixHeight = 16; // Param for different pixel layouts const bool kMatrixSerpentineLayout = true; const bool kMatrixVertical = false; // Set 'kMatrixSerpentineLayout' to false if your pixels are // laid out all running the same way, like this: // // 0 > 1 > 2 > 3 > 4 // | // .----<----<----<----' // | // 5 > 6 > 7 > 8 > 9 // | // .----<----<----<----' // | // 10 > 11 > 12 > 13 > 14 // | // .----<----<----<----' // | // 15 > 16 > 17 > 18 > 19 // // Set 'kMatrixSerpentineLayout' to true if your pixels are // laid out back-and-forth, like this: // // 0 > 1 > 2 > 3 > 4 // | // | // 9 < 8 < 7 < 6 < 5 // | // | // 10 > 11 > 12 > 13 > 14 // | // | // 19 < 18 < 17 < 16 < 15 // // Bonus vocabulary word: anything that goes one way // in one row, and then backwards in the next row, and so on // is call "boustrophedon", meaning "as the ox plows." // This function will return the right 'led index number' for // a given set of X and Y coordinates on your matrix. // IT DOES NOT CHECK THE COORDINATE BOUNDARIES. // That's up to you. Don't pass it bogus values. // // Use the "XY" function like this: // // for( uint8_t x = 0; x < kMatrixWidth; x++) { // for( uint8_t y = 0; y < kMatrixHeight; y++) { // // // Here's the x, y to 'led index' in action: // leds[ XY( x, y) ] = CHSV( random8(), 255, 255); // // } // } // // uint16_t XY( uint8_t x, uint8_t y) { uint16_t i; if( kMatrixSerpentineLayout == false) { if (kMatrixVertical == false) { i = (y * kMatrixWidth) + x; } else { i = kMatrixHeight * (kMatrixWidth - (x+1))+y; } } if( kMatrixSerpentineLayout == true) { if (kMatrixVertical == false) { if( y & 0x01) { // Odd rows run backwards uint8_t reverseX = (kMatrixWidth - 1) - x; i = (y * kMatrixWidth) + reverseX; } else { // Even rows run forwards i = (y * kMatrixWidth) + x; } } else { // vertical positioning if ( x & 0x01) { i = kMatrixHeight * (kMatrixWidth - (x+1))+y; } else { i = kMatrixHeight * (kMatrixWidth - x) - (y+1); } } } return i; } // Once you've gotten the basics working (AND NOT UNTIL THEN!) // here's a helpful technique that can be tricky to set up, but // then helps you avoid the needs for sprinkling array-bound-checking // throughout your code. // // It requires a careful attention to get it set up correctly, but // can potentially make your code smaller and faster. // // Suppose you have an 8 x 5 matrix of 40 LEDs. Normally, you'd // delcare your leds array like this: // CRGB leds[40]; // But instead of that, declare an LED buffer with one extra pixel in // it, "leds_plus_safety_pixel". Then declare "leds" as a pointer to // that array, but starting with the 2nd element (id=1) of that array: // CRGB leds_with_safety_pixel[41]; // CRGB* const leds( leds_plus_safety_pixel + 1); // Then you use the "leds" array as you normally would. // Now "leds[0..N]" are aliases for "leds_plus_safety_pixel[1..(N+1)]", // AND leds[-1] is now a legitimate and safe alias for leds_plus_safety_pixel[0]. // leds_plus_safety_pixel[0] aka leds[-1] is now your "safety pixel". // // Now instead of using the XY function above, use the one below, "XYsafe". // // If the X and Y values are 'in bounds', this function will return an index // into the visible led array, same as "XY" does. // HOWEVER -- and this is the trick -- if the X or Y values // are out of bounds, this function will return an index of -1. // And since leds[-1] is actually just an alias for leds_plus_safety_pixel[0], // it's a totally safe and legal place to access. And since the 'safety pixel' // falls 'outside' the visible part of the LED array, anything you write // there is hidden from view automatically. // Thus, this line of code is totally safe, regardless of the actual size of // your matrix: // leds[ XYsafe( random8(), random8() ) ] = CHSV( random8(), 255, 255); // // The only catch here is that while this makes it safe to read from and // write to 'any pixel', there's really only ONE 'safety pixel'. No matter // what out-of-bounds coordinates you write to, you'll really be writing to // that one safety pixel. And if you try to READ from the safety pixel, // you'll read whatever was written there last, reglardless of what coordinates // were supplied. #define NUM_LEDS (kMatrixWidth * kMatrixHeight) CRGB leds_plus_safety_pixel[ NUM_LEDS + 1]; CRGB* const leds( leds_plus_safety_pixel + 1); uint16_t XYsafe( uint8_t x, uint8_t y) { if( x >= kMatrixWidth) return -1; if( y >= kMatrixHeight) return -1; return XY(x,y); } // Demo that USES "XY" follows code below void loop() { uint32_t ms = millis(); int32_t yHueDelta32 = ((int32_t)cos16( ms * (27/1) ) * (350 / kMatrixWidth)); int32_t xHueDelta32 = ((int32_t)cos16( ms * (39/1) ) * (310 / kMatrixHeight)); DrawOneFrame( ms / 65536, yHueDelta32 / 32768, xHueDelta32 / 32768); if( ms < 5000 ) { FastLED.setBrightness( scale8( BRIGHTNESS, (ms * 256) / 5000)); } else { FastLED.setBrightness(BRIGHTNESS); } FastLED.show(); } void DrawOneFrame( uint8_t startHue8, int8_t yHueDelta8, int8_t xHueDelta8) { uint8_t lineStartHue = startHue8; for( uint8_t y = 0; y < kMatrixHeight; y++) { lineStartHue += yHueDelta8; uint8_t pixelHue = lineStartHue; for( uint8_t x = 0; x < kMatrixWidth; x++) { pixelHue += xHueDelta8; leds[ XY(x, y)] = CHSV( pixelHue, 255, 255); } } } void setup() { FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalSMD5050); FastLED.setBrightness( BRIGHTNESS ); }
Arduino实验场景图
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏
项目二十二:Mark 的 xy 坐标映射代码
实验开源代码
/* 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程) 实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏 项目二十二:Mark 的 xy 坐标映射代码 实验接线 Module UNO VCC —— 3.3V GND —— GND DI —— D6 */ #include <FastLED.h> // // Mark's xy coordinate mapping code. See the XYMatrix for more information on it. // // Params for width and height const uint8_t kMatrixWidth = 8; const uint8_t kMatrixHeight = 8; #define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) #define NUM_LEDS (kMatrixWidth * kMatrixHeight) // Param for different pixel layouts const bool kMatrixSerpentineLayout = true; uint16_t XY( uint8_t x, uint8_t y) { uint16_t i; if ( kMatrixSerpentineLayout == false) { i = (y * kMatrixWidth) + x; } if ( kMatrixSerpentineLayout == true) { if ( y & 0x01) { // Odd rows run backwards uint8_t reverseX = (kMatrixWidth - 1) - x; i = (y * kMatrixWidth) + reverseX; } else { // Even rows run forwards i = (y * kMatrixWidth) + x; } } return i; } // The leds CRGB leds[kMatrixWidth * kMatrixHeight]; // The 32bit version of our coordinates static uint16_t x; static uint16_t y; static uint16_t z; // We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll // use the z-axis for "time". speed determines how fast time moves forward. Try // 1 for a very slow moving effect, or 60 for something that ends up looking like // water. uint16_t speed = 3; // almost looks like a painting, moves very slowly //uint16_t speed = 20; // a nice starting speed, mixes well with a scale of 100 // uint16_t speed = 33; //uint16_t speed = 100; // wicked fast! // Scale determines how far apart the pixels in our noise matrix are. Try // changing these values around to see how it affects the motion of the display. The // higher the value of scale, the more "zoomed out" the noise iwll be. A value // of 1 will be so zoomed in, you'll mostly see solid colors. // uint16_t scale = 1; // mostly just solid colors // uint16_t scale = 4011; // very zoomed out and shimmery uint16_t scale = 311; // This is the array that we keep our computed noise values in uint16_t noise[MAX_DIMENSION][MAX_DIMENSION]; void setup() { // uncomment the following lines if you want to see FPS count information // Serial.begin(38400); // Serial.println("resetting!"); delay(3000); FastLED.addLeds<WS2811, 6, RGB>(leds, NUM_LEDS); FastLED.setBrightness(26); // Initialize our coordinates to some random values x = random16(); y = random16(); z = random16(); } // Fill the x/y array of 8-bit noise values using the inoise8 function. void fillnoise8() { for (int i = 0; i < MAX_DIMENSION; i++) { int ioffset = scale * i; for (int j = 0; j < MAX_DIMENSION; j++) { int joffset = scale * j; noise[i][j] = inoise8(x + ioffset, y + joffset, z); } } z += speed; } void loop() { static uint8_t ihue = 0; fillnoise8(); for (int i = 0; i < kMatrixWidth; i++) { for (int j = 0; j < kMatrixHeight; j++) { // We use the value at the (i,j) coordinate in the noise // array for our brightness, and the flipped value from (j,i) // for our pixel's hue. leds[XY(i, j)] = CHSV(noise[j][i], 255, noise[i][j]); // You can also explore other ways to constrain the hue used, like below // leds[XY(i,j)] = CHSV(ihue + (noise[j][i]>>2),255,noise[i][j]); } } ihue += 1; FastLED.show(); // delay(10); }
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏
项目二十三:随机不同像素布局的xy矩阵
实验开源代码
/* 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程) 实验一百三十八:64位 WS2812B8*8 xRGB 5050 LED模块 ws2812s像素点阵屏 项目二十三:随机不同像素布局的xy矩阵 实验接线 Module UNO VCC —— 3.3V GND —— GND DI —— D6 */ #include <FastLED.h> // Params for width and height const uint8_t kMatrixWidth = 8; const uint8_t kMatrixHeight = 8; #define NUM_LEDS (kMatrixWidth * kMatrixHeight) // Param for different pixel layouts #define kMatrixSerpentineLayout true // led array CRGB leds[kMatrixWidth * kMatrixHeight]; // x,y, & time values uint32_t x,y,v_time,hue_time,hxy; // Play with the values of the variables below and see what kinds of effects they // have! More octaves will make things slower. // how many octaves to use for the brightness and hue functions uint8_t octaves=1; uint8_t hue_octaves=3; // the 'distance' between points on the x and y axis int xscale=57771; int yscale=57771; // the 'distance' between x/y points for the hue noise int hue_scale=1; // how fast we move through time & hue noise int time_speed=1111; int hue_speed=31; // adjust these values to move along the x or y axis between frames int x_speed=331; int y_speed=1111; void loop() { // fill the led array 2/16-bit noise values fill_2dnoise16(leds, kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout, octaves,x,xscale,y,yscale,v_time, hue_octaves,hxy,hue_scale,hxy,hue_scale,hue_time, false); FastLED.show(); // adjust the intra-frame time values x += x_speed; y += y_speed; v_time += time_speed; hue_time += hue_speed; // delay(50); } void setup() { // initialize the x/y and time values random16_set_seed(8934); random16_add_entropy(analogRead(3)); Serial.begin(57600); Serial.println("resetting!"); delay(3000); FastLED.addLeds<WS2811,6,GRB>(leds,NUM_LEDS); FastLED.setBrightness(36); hxy = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); x = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); y = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); v_time = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); hue_time = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16(); }