/*
* Meteor Shower posted by Chemdoc77
* Based on the outstanding MeteorShower sketch by Jon Burroughs as seen in Adam bluebottleyellowboxyellyfish’s clock
* which Chemdoc77 slightly modified.
*/
#include <FastLED.h>
#define LED_PIN_OUT 3
#define LED_CHIPSET_TYPE WS2812B
#define NUM_LEDS 100
#define BRIGHTNESS 255
#define COLOR_ORDER RGB // Sắp sếp màu đúng theo thứ tự đỏ, xanh lá , xanh dương.
CRGB leds[NUM_LEDS];
#define analogReadPin A0
int speedValue = 1024; // giá trị tối đa của analog input (giá trị cao nhất của biến trở).
int sensorValue = 1024; // Giá trị mặc định của sensor điều khiển (biến trở).
int speedLeds = 40;
#define FRAMES_PER_SECOND 15
struct Meteo{ // Structure declaration
int name; // Ten
int position; // Vi Tri
}; // Structure variable
int meteobody[NUM_LEDS] ;
Meteo meteoArr[NUM_LEDS];
int meteoIndex = 0 ;
byte ledsX[NUM_LEDS][3];
boolean RAINBOWs = false;
boolean RANDOMpick = false;
uint8_t hue;
uint16_t timeframe;
byte idex = 0;
byte colorTIP = 0;
byte meteorLENGTH;
byte loopCount = 1; //low number loop counter
byte meteobornname = 0 ;
byte meteoposition = 0 ;
void setup() {
delay(3000) ; // Chờ khởi động hoàn tất để an toàn cho mạch.
Serial.begin(115200);
// độ dài mảng chứa số lượng meteo được tạo
init_speed_handle();
// put your setup code here, to run once:
//FastLED.addLeds<LED_CHIPSET_TYPE,LED_PIN_OUT,COLOR_ORDER>(leds,NUM_LEDS);
FastLED.addLeds<LED_CHIPSET_TYPE, LED_PIN_OUT, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS); // 0 - 255 độ sáng.
//FastLED.setMaxPowerInVoltsAndMilliamps(5,1500);
//set_max_power_indicator_LED(LED_PIN_OUT);
FastLED.clear();
FastLED.show();
}
//============================================
void loop() {
Serial.println("");
Serial.print("Speed Led : ");
Serial.println(speedLeds);
meteorShower();
}
//=============== Functions ==============
void init_speed_handle(){
sensorValue = analogRead(analogReadPin);
speedLeds = 1000 / FRAMES_PER_SECOND + (speedValue - sensorValue) ;
}
void meteorShower(){
//hue master
hue++;
//populate the leds[] with stored ledsX[] array data
for(byte i = 0; i < NUM_LEDS; i++ ) {
ledsX[i][0] = leds[i].r;
ledsX[i][1] = leds[i].g;
ledsX[i][2] = leds[i].b;
}
//clear the previous counter clockwise position
byte iCCW;
//we are keeping track of elapsed time
timeframe++; //fx timer
// //we are keeping track of position meteo
meteoposition++;
for(int i = 0; i <= meteoIndex; i++){
meteoArr[i].position++;
}
//meteorLENGTH fx is only shown for this time frame
if((timeframe >= 1) && (timeframe <= 280)) {
meteorLENGTH = 29;
}
if((timeframe > 280) && (timeframe <= 500)) {
meteorLENGTH = 45;
}
//RAINBOWs fx add rainbow tails during this time frame only
if((timeframe > 0) && (timeframe <= 280)) { RAINBOWs = true; }
else{ RAINBOWs = false; }
//keep our RAINBOWs within a specific range of hue
if(RAINBOWs == true){ hue = hue - 20; if(hue <= 0){ hue = 1; } }
//RANDOMpick fx is only enabled during this timeframe
if((timeframe > 600) && (timeframe <= 790)) { RANDOMpick = true; }
else{ RANDOMpick = false; }
//pick a random spot in the meteor switch case statement below
if (RANDOMpick == true){ idex = random8(46); }
else{
//increment the meteor display frame
idex++;
//make sure we don't drift into space
if (idex > meteorLENGTH) {
// khi idex = 0 thì bắt đầu tạo 1 meteo mới. và phát âm thanh bắn.
idex = 0;
Serial.println("============================");
Serial.print("Meteo was created mane : ");
Serial.println(meteobornname);
delay(10000);
} }
//meteorLENGTH is randomized during this timeframe only
if((timeframe > 790) && (timeframe <= 1090)) {
meteorLENGTH = random8(10, 32);
}
//during this point in the animation timeframe
if(timeframe == 1180) {
//reset the timeframe
timeframe = 0;
//increment the loop counter
loopCount++;
}
//during this part of the loopCount, all meteors have a white colored tip
if(loopCount == 1) { colorTIP = 0; }
if(loopCount == 2) { colorTIP = 1; }
if(loopCount == 3) { colorTIP = random8(11); }
//end of the desired fx, reset the variable for the next time around
if(loopCount == 4) {
colorTIP = 0;
loopCount = 0;
}
//there are two switch case statements nestled into one another
//we always want to control the color of the meteor tip
//the other controls the actual meteor animation in 45 frames/case statements
switch (idex) {
case 0:
switch (colorTIP){
case 0:
leds[0] = CHSV(hue, 255, 255);
break;
case 1:
leds[0] = CRGB(100,100,100);
break;
case 2:
leds[0] = CRGB::Yellow;
break;
case 3:
leds[0] = CRGB::Violet;
break;
case 4:
leds[0] = CRGB::Green;
break;
case 5:
leds[0] = CRGB::Purple;
break;
case 6:
leds[0] = CRGB::Orange;
break;
case 7:
leds[0] = CRGB::Cyan;
break;
case 8:
leds[0] = CRGB::GreenYellow;
break;
case 9:
leds[0] = CRGB::Magenta;
break;
case 10:
leds[0] = CRGB::SkyBlue;
}
break;
case 1:
leds[0] = CHSV((hue - 20), 255, 210);
break;
case 2:
leds[0] = CHSV((hue - 22), 255, 180);
break;
case 3:
leds[0] = CHSV((hue - 23), 255, 150);
break;
case 4:
leds[0] = CHSV((hue - 24), 255, 110);
break;
case 5:
leds[0] = CHSV((hue - 25), 255, 90);
break;
case 6:
leds[0] = CHSV((hue - 26), 160, 60);
break;
case 7:
leds[0] = CHSV((hue - 27), 140, 40);
break;
case 8:
leds[0] = CHSV((hue - 28), 120, 20);
break;
case 9:
leds[0] = CHSV((hue - 29), 100, 20);
break;
case 10:
leds[0] = CRGB::Black;
break;
case 11:
leds[0] = CRGB::Black;
break;
case 12:
leds[0] = CRGB::Black;
break;
case 13:
leds[0] = CRGB::Black;
break;
case 14:
leds[0] = CRGB::Black;
break;
case 15:
leds[0] = CRGB::Black;
break;
case 16:
leds[0] = CRGB::Black;
break;
case 17:
leds[0] = CRGB::Black;
break;
case 18:
leds[0] = CRGB::Black;
break;
case 19:
leds[0] = CRGB::Black;
break;
case 20:
leds[0] = CRGB::Black;
break;
case 21:
leds[0] = CRGB::Black;
break;
case 22:
leds[0] = CRGB::Black;
break;
case 23:
leds[0] = CRGB::Black;
break;
case 24:
leds[0] = CRGB::Black;
break;
case 25:
leds[0] = CRGB::Black;
break;
case 26:
leds[0] = CRGB::Black;
break;
case 27:
leds[0] = CRGB::Black;
break;
case 28:
leds[0] = CRGB::Black;
break;
case 29:
leds[0] = CRGB::Black;
break;
case 30:
leds[0] = CRGB::Black;
break;
case 31:
leds[0] = CRGB::Black;
break;
case 32:
leds[0] = CRGB::Black;
break;
case 33:
leds[0] = CRGB::Black;
break;
case 34:
leds[0] = CRGB::Black;
break;
case 35:
leds[0] = CRGB::Black;
break;
case 36:
leds[0] = CRGB::Black;
break;
case 37:
leds[0] = CRGB::Black;
break;
case 38:
leds[0] = CRGB::Black;
break;
case 39:
leds[0] = CRGB::Black;
break;
case 40:
leds[0] = CRGB::Black;
break;
case 41:
leds[0] = CRGB::Black;
break;
case 42:
leds[0] = CRGB::Black;
break;
case 43:
leds[0] = CRGB::Black;
break;
case 44:
leds[0] = CRGB::Black;
break;
case 45:
leds[0] = CRGB::Black;
break;
}
//copy the LED Array
for(byte i = 1; i < NUM_LEDS; i++ ) {
iCCW = adjacent_ccw(i);
leds[i].r = ledsX[iCCW][0];
leds[i].g = ledsX[iCCW][1];
leds[i].b = ledsX[iCCW][2];
}
Serial.print("time frame : ");
Serial.println(timeframe);
Serial.print("idex : ");
Serial.println(idex);
Serial.print("meteo : ");
Serial.print(meteobornname);
Serial.print(" meteo position : ");
Serial.println(meteoposition);
meteobody[meteobornname] = meteoposition;
Serial.print("meteo : ");
Serial.print(meteobornname);
Serial.print(" at position : ");
Serial.println(meteoposition);
for(int i = 0; i <= meteoIndex; i++){
Serial.print("meteoArr[");
Serial.print(i);
Serial.print("].name : ");
Serial.print(meteoArr[i].name);
Serial.print(" meteoArr[");
Serial.print(i);
Serial.print("].position : ");
Serial.println(meteoArr[i].position);
}
if(idex == 0 ){
meteobornname++ ;
meteoIndex++ ;
meteoArr[meteoIndex].name = meteobornname;
meteoArr[meteoIndex].position = 0;
}
if(meteobody[meteobornname] == NUM_LEDS){
meteoposition = 0;
Serial.print("Meteo was destroy .");
delay(10000);
}
//show the blinky
FastLED.show();
//control the animation speed/frame rate
init_speed_handle();
delay(speedLeds);
}
//find the adjacent counter clockwise postion of the led
//funkboxing code snippet
byte adjacent_ccw(byte i) {
byte r;
if (i > 0) { r = i - 1; }
else { r = NUM_LEDS - 1; }
return r;
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
neopixels:DOUT
neopixels:VDD
neopixels:VSS
neopixels:DIN