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();
}