Components and supplies
Power Supply 5V 10A
WS2811 Addressable LED String
Capacitor 1000 uF
Arduino UNO
Apps and platforms
Visual Studio 2015
Project description
Code
doSnow()
c_cpp
This is the core function that handles the falling snow. Sorry, it's not cleaned up, but hopefully it's documented enough for others to use.
1/********************************************** 2* 3* doSnow() 4* Let it snow, let it snow! 5* 6**********************************************/ 7int lightSpot = 0; 8// ringCutoffs is the critical part. Starting with light 0, you need to identify the lights above 9// one another in a straight line. If you light these all, you get a vertical line up one side of 10// the tree. You need to use the Serial.available if statement at the start to experimentally 11// figure out which light numbers those are and adjust the length and contents of the array 12// to match YOUR tree. 13// Controls: Send '=' to the serial port to increment to the next light, '-' to go back a light 14// You'll need to change your NUM_OF_RINGS to match the number of times your lights go around the tree. 15#define NUM_RINGS 11 16// Note that the first ring needs to start at 0! 17int ringCutoffs[NUM_RINGS] = {0, 54, 95, 135, 167, 196, 218, 240, 262, 281, 295 }; 18int ringRatios[NUM_RINGS - 1]; 19char cBuff; 20int snowTemp; 21float snowPct; 22#define SNOW_PWR 50 23#define SNOW_MELT_HEAT 1 24#define SNOW_MELT_HOW_MANY_RINGS_HIGH 3 25#define SNOW_FULL_CUTOFF 230 26#define NUM_FLAKES_TO_FALL_PER_FRAME 4 27void doSnow() { 28 // STEP 1 - SET UP YOUR TREE 29 // THIS IS THE PART YOU USE THE FIRST TIME TO SET UP YOUR TREE 30 // Uncommend this block (and comment the rest). Use '=' and '-' to 31 // move your 'cursor' light around and experimentally get the 32 // values you need to put in the ringCutoffs array. 33 //if (Serial.available() > 0) { 34 // cBuff = Serial.read(); 35 // switch (cBuff) { 36 // case '=': 37 // lightSpot++; 38 // break; 39 // case '-': 40 // lightSpot--; 41 // break; 42 // } 43 // Serial.println(lightSpot); 44 //} 45 //fill_solid(leds, NUM_LEDS, CRGB::Black); 46 //leds[lightSpot] = CRGB::White; 47 //FastLED.delay(DELAY_TIME_FAST); 48 49 // STEP 2 - DOUBLE-CHECK 50 // When you're done filling in ringCutoffs, uncomment this block and check your line. See if it goes 51 // fairly straight up the tree. 52 //fill_solid(leds, NUM_LEDS, CRGB::Black); 53 //for (ringCounter = 0; ringCounter < NUM_OF_RINGS; ringCounter++) { 54 // leds[ringCutoffs[i]] = CRGB::White; 55 //} 56 //FastLED.delay(DELAY_TIME_FAST); 57 58 // STEP 3 - ENJOY THE SNOW 59 // Uncomment this code block and it will do the rest! 60 // Algorithm: 61 // Generate a random flake 62 // Start at the bottom ring, and float them all down 63 64 for (ring = 0; ring < NUM_RINGS - 1; ring++) { 65 for (led = ringCutoffs[ring]; led < ringCutoffs[ring + 1]; led++) { 66 if (snowFlakes[led] > 0) { 67 if (ring > 0) { 68 snowTemp = ((float)((float)(led - ringCutoffs[ring]) / (float)(ringCutoffs[ring + 1] - ringCutoffs[ring])) * 69 (ringCutoffs[ring] - ringCutoffs[ring - 1])) + 70 ringCutoffs[ring - 1] + 71 (random8(3) - 1); 72 if (snowFlakes[snowTemp] < SNOW_FULL_CUTOFF) { 73 //Serial.print("Going from "); 74 //Serial.print(led); 75 //Serial.print(" to "); 76 //Serial.println(snowTemp); 77 snowFlakes[snowTemp] = max (snowFlakes[led], min (250, snowFlakes[snowTemp] + SNOW_PWR)); 78 snowFlakes[led] = 0; 79 } 80 //Serial.print("ON: "); 81 } 82 } 83 //Serial.println(led); 84 } 85 } 86 for (led = ringCutoffs[NUM_RINGS - 1]; led < NUM_LEDS; led++) { 87 if (snowFlakes[led] > 0) { 88 snowTemp = ((float)((float)(led - ringCutoffs[NUM_RINGS - 1]) / (float)(NUM_LEDS - ringCutoffs[NUM_RINGS - 1])) * 89 (ringCutoffs[NUM_RINGS - 1] - ringCutoffs[NUM_RINGS - 2])) + 90 ringCutoffs[NUM_RINGS - 2] + 91 (random8(3) - 1); 92 //Serial.println(led - ringCutoffs[NUM_RINGS - 1]); 93 //Serial.println(NUM_LEDS - ringCutoffs[NUM_RINGS - 1]); 94 //Serial.println((float)((float)(led - ringCutoffs[NUM_RINGS - 1]) / (float)(NUM_LEDS - ringCutoffs[NUM_RINGS - 1]))); 95 //Serial.println(ringCutoffs[NUM_RINGS - 1] - ringCutoffs[NUM_RINGS - 2]); 96 //Serial.println((float)((float)(led - ringCutoffs[NUM_RINGS - 1]) / (float)(NUM_LEDS - ringCutoffs[NUM_RINGS - 1])) * (ringCutoffs[NUM_RINGS - 1] - ringCutoffs[NUM_RINGS - 2])); 97 //Serial.println(((float)((float)(led - ringCutoffs[NUM_RINGS - 1]) / (float)(NUM_LEDS - ringCutoffs[NUM_RINGS - 1])) * (ringCutoffs[NUM_RINGS - 1] - ringCutoffs[NUM_RINGS - 2])) + ringCutoffs[NUM_RINGS - 2]); 98 if (snowFlakes[snowTemp] < SNOW_FULL_CUTOFF) { 99 //Serial.print("Going from "); 100 //Serial.print(led); 101 //Serial.print(" to "); 102 //Serial.println(snowTemp); 103 snowFlakes[snowTemp] = min(250, snowFlakes[snowTemp] + SNOW_PWR); 104 snowFlakes[led] = 0; 105 } 106 //Serial.print("ON: "); 107 } 108 //Serial.println(led); 109 } 110 for (led = 0; led < ringCutoffs[SNOW_MELT_HOW_MANY_RINGS_HIGH]; led++) { 111 snowFlakes[led] = max(0, snowFlakes[led] - SNOW_MELT_HEAT); 112 } 113 for (snowTemp = 0; snowTemp < NUM_FLAKES_TO_FALL_PER_FRAME; snowTemp++) { 114 led = ringCutoffs[NUM_RINGS - 1] + (random8((NUM_LEDS - ringCutoffs[NUM_RINGS - 1]))); 115 snowFlakes[led] = min (250, snowFlakes[led] + SNOW_PWR); 116 } 117 //fill_solid(leds, NUM_LEDS, CRGB::Black); 118 for (led = 0; led < NUM_LEDS; led++) { 119 //if (snowFlakes[led] > 0) { 120 leds[led] = CRGB(snowFlakes[led], snowFlakes[led], snowFlakes[led]); 121 //} 122 } 123 leds[0] = CRGB::Yellow; 124 FastLED.delay(150); 125}
doSnow()
c_cpp
This is the core function that handles the falling snow. Sorry, it's not cleaned up, but hopefully it's documented enough for others to use.
1/********************************************** 2* 3* doSnow() 4* Let it snow, let it snow! 5* 6**********************************************/ 7int lightSpot = 0; 8// ringCutoffs is the critical part. Starting with light 0, you need to identify the lights above 9// one another in a straight line. If you light these all, you get a vertical line up one side of 10// the tree. You need to use the Serial.available if statement at the start to experimentally 11// figure out which light numbers those are and adjust the length and contents of the array 12// to match YOUR tree. 13// Controls: Send '=' to the serial port to increment to the next light, '-' to go back a light 14// You'll need to change your NUM_OF_RINGS to match the number of times your lights go around the tree. 15#define NUM_RINGS 11 16// Note that the first ring needs to start at 0! 17int ringCutoffs[NUM_RINGS] = {0, 54, 95, 135, 167, 196, 218, 240, 262, 281, 295 }; 18int ringRatios[NUM_RINGS - 1]; 19char cBuff; 20int snowTemp; 21float snowPct; 22#define SNOW_PWR 50 23#define SNOW_MELT_HEAT 1 24#define SNOW_MELT_HOW_MANY_RINGS_HIGH 3 25#define SNOW_FULL_CUTOFF 230 26#define NUM_FLAKES_TO_FALL_PER_FRAME 4 27void doSnow() { 28 // STEP 1 - SET UP YOUR TREE 29 // THIS IS THE PART YOU USE THE FIRST TIME TO SET UP YOUR TREE 30 // Uncommend this block (and comment the rest). Use '=' and '-' to 31 // move your 'cursor' light around and experimentally get the 32 // values you need to put in the ringCutoffs array. 33 //if (Serial.available() > 0) { 34 // cBuff = Serial.read(); 35 // switch (cBuff) { 36 // case '=': 37 // lightSpot++; 38 // break; 39 // case '-': 40 // lightSpot--; 41 // break; 42 // } 43 // Serial.println(lightSpot); 44 //} 45 //fill_solid(leds, NUM_LEDS, CRGB::Black); 46 //leds[lightSpot] = CRGB::White; 47 //FastLED.delay(DELAY_TIME_FAST); 48 49 // STEP 2 - DOUBLE-CHECK 50 // When you're done filling in ringCutoffs, uncomment this block and check your line. See if it goes 51 // fairly straight up the tree. 52 //fill_solid(leds, NUM_LEDS, CRGB::Black); 53 //for (ringCounter = 0; ringCounter < NUM_OF_RINGS; ringCounter++) { 54 // leds[ringCutoffs[i]] = CRGB::White; 55 //} 56 //FastLED.delay(DELAY_TIME_FAST); 57 58 // STEP 3 - ENJOY THE SNOW 59 // Uncomment this code block and it will do the rest! 60 // Algorithm: 61 // Generate a random flake 62 // Start at the bottom ring, and float them all down 63 64 for (ring = 0; ring < NUM_RINGS - 1; ring++) { 65 for (led = ringCutoffs[ring]; led < ringCutoffs[ring + 1]; led++) { 66 if (snowFlakes[led] > 0) { 67 if (ring > 0) { 68 snowTemp = ((float)((float)(led - ringCutoffs[ring]) / (float)(ringCutoffs[ring + 1] - ringCutoffs[ring])) * 69 (ringCutoffs[ring] - ringCutoffs[ring - 1])) + 70 ringCutoffs[ring - 1] + 71 (random8(3) - 1); 72 if (snowFlakes[snowTemp] < SNOW_FULL_CUTOFF) { 73 //Serial.print("Going from "); 74 //Serial.print(led); 75 //Serial.print(" to "); 76 //Serial.println(snowTemp); 77 snowFlakes[snowTemp] = max (snowFlakes[led], min (250, snowFlakes[snowTemp] + SNOW_PWR)); 78 snowFlakes[led] = 0; 79 } 80 //Serial.print("ON: "); 81 } 82 } 83 //Serial.println(led); 84 } 85 } 86 for (led = ringCutoffs[NUM_RINGS - 1]; led < NUM_LEDS; led++) { 87 if (snowFlakes[led] > 0) { 88 snowTemp = ((float)((float)(led - ringCutoffs[NUM_RINGS - 1]) / (float)(NUM_LEDS - ringCutoffs[NUM_RINGS - 1])) * 89 (ringCutoffs[NUM_RINGS - 1] - ringCutoffs[NUM_RINGS - 2])) + 90 ringCutoffs[NUM_RINGS - 2] + 91 (random8(3) - 1); 92 //Serial.println(led - ringCutoffs[NUM_RINGS - 1]); 93 //Serial.println(NUM_LEDS - ringCutoffs[NUM_RINGS - 1]); 94 //Serial.println((float)((float)(led - ringCutoffs[NUM_RINGS - 1]) / (float)(NUM_LEDS - ringCutoffs[NUM_RINGS - 1]))); 95 //Serial.println(ringCutoffs[NUM_RINGS - 1] - ringCutoffs[NUM_RINGS - 2]); 96 //Serial.println((float)((float)(led - ringCutoffs[NUM_RINGS - 1]) / (float)(NUM_LEDS - ringCutoffs[NUM_RINGS - 1])) * (ringCutoffs[NUM_RINGS - 1] - ringCutoffs[NUM_RINGS - 2])); 97 //Serial.println(((float)((float)(led - ringCutoffs[NUM_RINGS - 1]) / (float)(NUM_LEDS - ringCutoffs[NUM_RINGS - 1])) * (ringCutoffs[NUM_RINGS - 1] - ringCutoffs[NUM_RINGS - 2])) + ringCutoffs[NUM_RINGS - 2]); 98 if (snowFlakes[snowTemp] < SNOW_FULL_CUTOFF) { 99 //Serial.print("Going from "); 100 //Serial.print(led); 101 //Serial.print(" to "); 102 //Serial.println(snowTemp); 103 snowFlakes[snowTemp] = min(250, snowFlakes[snowTemp] + SNOW_PWR); 104 snowFlakes[led] = 0; 105 } 106 //Serial.print("ON: "); 107 } 108 //Serial.println(led); 109 } 110 for (led = 0; led < ringCutoffs[SNOW_MELT_HOW_MANY_RINGS_HIGH]; led++) { 111 snowFlakes[led] = max(0, snowFlakes[led] - SNOW_MELT_HEAT); 112 } 113 for (snowTemp = 0; snowTemp < NUM_FLAKES_TO_FALL_PER_FRAME; snowTemp++) { 114 led = ringCutoffs[NUM_RINGS - 1] + (random8((NUM_LEDS - ringCutoffs[NUM_RINGS - 1]))); 115 snowFlakes[led] = min (250, snowFlakes[led] + SNOW_PWR); 116 } 117 //fill_solid(leds, NUM_LEDS, CRGB::Black); 118 for (led = 0; led < NUM_LEDS; led++) { 119 //if (snowFlakes[led] > 0) { 120 leds[led] = CRGB(snowFlakes[led], snowFlakes[led], snowFlakes[led]); 121 //} 122 } 123 leds[0] = CRGB::Yellow; 124 FastLED.delay(150); 125}
Downloadable files
Basic Uno / LED String setup with capacitor for spike protection
Simple setup for LED Strings
Basic Uno / LED String setup with capacitor for spike protection
Basic Uno / LED String setup with capacitor for spike protection
Simple setup for LED Strings
Basic Uno / LED String setup with capacitor for spike protection
LED String w/ capacitor for spike protection - image
LED String w/ capacitor for spike protection - image
Comments
Only logged in users can leave comments
GameMaker
0 Followers
•0 Projects
Table of contents
Intro
0
0