Created
December 27, 2024 23:45
-
-
Save AdskiyPonchik/a62ba49942bc07529c65d238013459fe to your computer and use it in GitHub Desktop.
Code for garland
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// HAZI TECH | |
// Program by Hasitha Jayasundara | |
// Subscribe to my YouTube Channel - http://www.youtube.com/c/HAZITECH?sub_confirmation=1 | |
#include "Arduino.h" | |
#include <FastLED.h> // Нужно добавить эту библиотеку если будет ругаться на отсутствие ее | |
FASTLED_USING_NAMESPACE | |
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000) | |
#warning "Requires FastLED 3.1 or later; check github for latest code." | |
#endif | |
#define DATA_PIN 13 // Пин подключения управляющего провода | |
#define buttonPin 8 //Button pin | |
#define LED_TYPE WS2811 | |
#define COLOR_ORDER GRB | |
#define NUM_LEDS 43 //Total no of LEDs /количество светодиодов на ленте изменить при необходимости. | |
#define UPDATES_PER_SECOND 150 | |
CRGB leds[NUM_LEDS]; | |
#define BRIGHTNESS 255 | |
#define FRAMES_PER_SECOND 255 | |
#define COOLING 55 | |
#define SPARKING 120 | |
bool gReverseDirection = false; | |
CRGBPalette16 gPal; | |
CRGBPalette16 pacifica_palette_1 = | |
{ 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117, | |
0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x14554B, 0x28AA50 }; | |
CRGBPalette16 pacifica_palette_2 = | |
{ 0x000507, 0x000409, 0x00030B, 0x00030D, 0x000210, 0x000212, 0x000114, 0x000117, | |
0x000019, 0x00001C, 0x000026, 0x000031, 0x00003B, 0x000046, 0x0C5F52, 0x19BE5F }; | |
CRGBPalette16 pacifica_palette_3 = | |
{ 0x000208, 0x00030E, 0x000514, 0x00061A, 0x000820, 0x000927, 0x000B2D, 0x000C33, | |
0x000E39, 0x001040, 0x001450, 0x001860, 0x001C70, 0x002080, 0x1040BF, 0x2060FF }; | |
CRGBPalette16 currentPalette; | |
TBlendType currentBlending; | |
extern CRGBPalette16 myRedWhiteBluePalette; | |
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM; | |
void setup() { | |
delay( 1000 ); // power-up safety delay | |
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip ); | |
FastLED.setBrightness( BRIGHTNESS ); | |
currentPalette = RainbowColors_p; | |
currentBlending = LINEARBLEND;; | |
gPal = HeatColors_p; | |
} | |
// List of patterns to cycle through. Each is defined as a separate function below. | |
typedef void (*SimplePatternList[])(); | |
SimplePatternList gPatterns = { second_light, pride, confetti, cylon, colorpalete, rainbow, sinelon, first_light, juggle, bpm, Fire2012 }; | |
//SimplePatternList gPatterns = { Fire2012 }; | |
uint8_t gCurrentPatternNumber = 0; // Index number of which pattern is current | |
uint8_t gHue = 0; // rotating "base color" used by many of the patterns | |
int buttonState; | |
void loop() | |
{ | |
// Call the current pattern function once, updating the 'leds' array | |
gPatterns[gCurrentPatternNumber](); | |
// send the 'leds' array out to the actual LED strip | |
FastLED.show(); | |
// insert a delay to keep the framerate modest | |
FastLED.delay(1000/FRAMES_PER_SECOND); | |
// do some periodic updates | |
EVERY_N_MILLISECONDS( 20 ) { gHue++; } // slowly cycle the "base color" through the rainbow | |
//EVERY_N_SECONDS( 20 ) { nextPattern(); } // change patterns periodically | |
int currentButtonState = digitalRead(buttonPin); | |
if (currentButtonState == HIGH && buttonState == LOW) { | |
delay(50); // Задержка для устранения дребезга | |
if (digitalRead(buttonPin) == HIGH) { | |
nextPattern(); | |
} | |
} | |
buttonState = currentButtonState; | |
} | |
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) | |
void nextPattern() | |
{ | |
// add one to the current pattern number, and wrap around at the end | |
gCurrentPatternNumber = (gCurrentPatternNumber + 1) % ARRAY_SIZE(gPatterns); | |
} | |
void rainbow() | |
{ | |
// FastLED's built-in rainbow generator | |
fill_rainbow( leds, NUM_LEDS, gHue, 7); | |
} | |
void confetti() | |
{ | |
// random colored speckles that blink in and fade smoothly | |
fadeToBlackBy( leds, NUM_LEDS, 10); | |
int pos = random16(NUM_LEDS); | |
leds[pos] += CHSV( gHue + random8(64), 200, 255); | |
} | |
void sinelon() | |
{ | |
// a colored dot sweeping back and forth, with fading trails | |
fadeToBlackBy( leds, NUM_LEDS, 20); | |
int pos = beatsin16( 7, 0, NUM_LEDS-1 ); | |
leds[pos] += CHSV( gHue, 255, 192); | |
} | |
void bpm() | |
{ | |
// colored stripes pulsing at a defined Beats-Per-Minute (BPM) | |
uint8_t BeatsPerMinute = 62; | |
CRGBPalette16 palette = PartyColors_p; | |
uint8_t beat = beatsin8( BeatsPerMinute, 64, 255); | |
for( int i = 0; i < NUM_LEDS; i++) { //9948 | |
leds[i] = ColorFromPalette(palette, gHue+(i*2), beat-gHue+(i*10)); | |
} | |
} | |
void juggle() { | |
// eight colored dots, weaving in and out of sync with each other | |
fadeToBlackBy( leds, NUM_LEDS, 20); | |
byte dothue = 0; | |
for( int i = 0; i < 8; i++) { | |
leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255); | |
dothue += 32; | |
} | |
} | |
/*void Fire2012() | |
{ | |
// Array of temperature readings at each simulation cell | |
static byte heat[NUM_LEDS]; | |
// Step 1. Cool down every cell a little | |
for( int i = 0; i < NUM_LEDS; i++) { | |
heat[i] = qsub8( heat[i], random8(0, ((COOLING * 10) / NUM_LEDS) + 2)); | |
} | |
// Step 2. Heat from each cell drifts 'up' and diffuses a little | |
for( int k= NUM_LEDS - 1; k >= 2; k--) { | |
heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; | |
} | |
// Step 3. Randomly ignite new 'sparks' of heat near the bottom | |
if( random8() < SPARKING ) { | |
int y = random8(7); | |
heat[y] = qadd8( heat[y], random8(160,255) ); | |
} | |
// Step 4. Map from heat cells to LED colors | |
for( int j = 0; j < NUM_LEDS; j++) { | |
CRGB color = HeatColor( heat[j]); | |
int pixelnumber; | |
if( gReverseDirection ) { | |
pixelnumber = (NUM_LEDS-1) - j; | |
} else { | |
pixelnumber = j; | |
} | |
leds[pixelnumber] = color; | |
} | |
} | |
*/ | |
void Fire2012() { | |
static byte hues[NUM_LEDS] = {0}; | |
static int hueDirection[NUM_LEDS] = {0}; | |
static bool initialized = false; | |
if (!initialized) { | |
for (int i = 0; i < NUM_LEDS; i++) { | |
hues[i] = random8(60, 90); | |
} | |
initialized = true; | |
} | |
for (int i = 0; i < NUM_LEDS; i++) { | |
if (hueDirection[i] == 0) { | |
hues[i]++; | |
if (hues[i] >= 90) { // жёлтый (60) до оранжево-красного (90) | |
hueDirection[i] = 1; //смена направления | |
} | |
} else { | |
hues[i]--; | |
if (hues[i] <= 60) { | |
hueDirection[i] = 0; | |
} | |
} | |
leds[i] = CHSV(hues[i], 255, BRIGHTNESS); // полная насыщенность и яркость | |
} | |
FastLED.show(); | |
delay(5); | |
} | |
void first_light(){ | |
static uint8_t hue = 0; | |
for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) { | |
// Turn our current led on to white, then show the leds | |
leds[whiteLed] = CHSV(hue++, 255, 255); | |
// Show the leds (only one of which is set to white, from above) | |
FastLED.show(); | |
// Wait a little bit | |
delay(1); | |
// Turn our current led back to black for the next loop around | |
leds[whiteLed] = leds[whiteLed] = CRGB::Black; | |
} | |
} | |
void second_light(){ | |
static uint8_t hue = 0; | |
for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) { | |
// Turn our current led on to white, then show the leds | |
leds[whiteLed] = CHSV(hue++, 255, 255); | |
// Show the leds (only one of which is set to white, from above) | |
FastLED.show(); | |
// Wait a little bit | |
delay(20); | |
// Turn our current led back to black for the next loop around | |
leds[whiteLed] = CHSV(hue++, 255, 255); | |
} | |
} | |
void cylon(){ | |
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(50); | |
} | |
//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(50); | |
} | |
} | |
void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } } | |
void rgbsetdemo(){ | |
CRGBArray<NUM_LEDS> leds; | |
FastLED.addLeds<NEOPIXEL,DATA_PIN>(leds, NUM_LEDS); | |
static uint8_t hue; | |
for(int i = 0; i < NUM_LEDS/2; i++) { | |
// fade everything out | |
leds.fadeToBlackBy(20); | |
// let's set an led value | |
leds[i] = CHSV(hue++,255,255); | |
// now, let's first 20 leds to the top 20 leds, | |
leds(NUM_LEDS/2,NUM_LEDS-1) = leds(NUM_LEDS/2 - 1 ,0); | |
FastLED.delay(13); | |
} | |
} | |
void pacifica_loop() | |
{ | |
// Increment the four "color index start" counters, one for each wave layer. | |
// Each is incremented at a different speed, and the speeds vary over time. | |
static uint16_t sCIStart1, sCIStart2, sCIStart3, sCIStart4; | |
static uint32_t sLastms = 0; | |
uint32_t ms = GET_MILLIS(); | |
uint32_t deltams = ms - sLastms; | |
sLastms = ms; | |
uint16_t speedfactor1 = beatsin16(3, 179, 269); | |
uint16_t speedfactor2 = beatsin16(4, 179, 269); | |
uint32_t deltams1 = (deltams * speedfactor1) / 256; | |
uint32_t deltams2 = (deltams * speedfactor2) / 256; | |
uint32_t deltams21 = (deltams1 + deltams2) / 2; | |
sCIStart1 += (deltams1 * beatsin88(1011,10,13)); | |
sCIStart2 -= (deltams21 * beatsin88(777,8,11)); | |
sCIStart3 -= (deltams1 * beatsin88(501,5,7)); | |
sCIStart4 -= (deltams2 * beatsin88(257,4,6)); | |
// Clear out the LED array to a dim background blue-green | |
fill_solid( leds, NUM_LEDS, CRGB( 2, 6, 10)); | |
// Render each of four layers, with different scales and speeds, that vary over time | |
pacifica_one_layer( pacifica_palette_1, sCIStart1, beatsin16( 3, 11 * 256, 14 * 256), beatsin8( 10, 70, 130), 0-beat16( 301) ); | |
pacifica_one_layer( pacifica_palette_2, sCIStart2, beatsin16( 4, 6 * 256, 9 * 256), beatsin8( 17, 40, 80), beat16( 401) ); | |
pacifica_one_layer( pacifica_palette_3, sCIStart3, 6 * 256, beatsin8( 9, 10,38), 0-beat16(503)); | |
pacifica_one_layer( pacifica_palette_3, sCIStart4, 5 * 256, beatsin8( 8, 10,28), beat16(601)); | |
// Add brighter 'whitecaps' where the waves lines up more | |
pacifica_add_whitecaps(); | |
// Deepen the blues and greens a bit | |
pacifica_deepen_colors(); | |
} | |
// Add one layer of waves into the led array | |
void pacifica_one_layer( CRGBPalette16& p, uint16_t cistart, uint16_t wavescale, uint8_t bri, uint16_t ioff) | |
{ | |
uint16_t ci = cistart; | |
uint16_t waveangle = ioff; | |
uint16_t wavescale_half = (wavescale / 2) + 20; | |
for( uint16_t i = 0; i < NUM_LEDS; i++) { | |
waveangle += 250; | |
uint16_t s16 = sin16( waveangle ) + 32768; | |
uint16_t cs = scale16( s16 , wavescale_half ) + wavescale_half; | |
ci += cs; | |
uint16_t sindex16 = sin16( ci) + 32768; | |
uint8_t sindex8 = scale16( sindex16, 240); | |
CRGB c = ColorFromPalette( p, sindex8, bri, LINEARBLEND); | |
leds[i] += c; | |
} | |
} | |
// Add extra 'white' to areas where the four layers of light have lined up brightly | |
void pacifica_add_whitecaps() | |
{ | |
uint8_t basethreshold = beatsin8( 9, 55, 65); | |
uint8_t wave = beat8( 7 ); | |
for( uint16_t i = 0; i < NUM_LEDS; i++) { | |
uint8_t threshold = scale8( sin8( wave), 20) + basethreshold; | |
wave += 7; | |
uint8_t l = leds[i].getAverageLight(); | |
if( l > threshold) { | |
uint8_t overage = l - threshold; | |
uint8_t overage2 = qadd8( overage, overage); | |
leds[i] += CRGB( overage, overage2, qadd8( overage2, overage2)); | |
} | |
} | |
} | |
// Deepen the blues and greens | |
void pacifica_deepen_colors() | |
{ | |
for( uint16_t i = 0; i < NUM_LEDS; i++) { | |
leds[i].blue = scale8( leds[i].blue, 145); | |
leds[i].green= scale8( leds[i].green, 200); | |
leds[i] |= CRGB( 2, 5, 7); | |
} | |
} | |
void colorpalete(){ | |
ChangePalettePeriodically(); | |
static uint8_t startIndex = 0; | |
startIndex = startIndex + 1; /* motion speed */ | |
FillLEDsFromPaletteColors( startIndex); | |
FastLED.show(); | |
FastLED.delay(1000 / UPDATES_PER_SECOND); | |
} | |
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); | |
} | |
} | |
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; | |
} | |
} | |
// There are several different palettes of colors demonstrated here. | |
// | |
// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p, | |
// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p. | |
// | |
// Additionally, you can manually define your own color palettes, or you can write | |
// code that creates color palettes on the fly. All are shown here. | |
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()); | |
} | |
} | |
// This function sets up a palette of black and white stripes, | |
// using code. Since the palette is effectively an array of | |
// sixteen CRGB colors, the various fill_* functions can be used | |
// to set them up. | |
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 ); | |
} | |
// This example shows how to set up a static color palette | |
// which is stored in PROGMEM (flash), which is almost always more | |
// plentiful than RAM. A static PROGMEM palette like this | |
// takes up 64 bytes of flash. | |
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 | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment