/* Sync LEDs to "Wizards in Winter" by Trans-Siberian Orchestra! Numbering I use for my snowflake: 1 6 2 <-- row 2 5 3 <-- row 3 4 See the original (non PWM) code for more documentation! Compared to the original (non PWM) code, the goal of this code is to use PWM to do fading! The analogWrite() function is what controls PWM. Sadly, Arduinos have a limited number of timers. The IRremote library uses timer2, so, unless you set variable receiver to false, timer2 is unavailable for PWM. A normal Arduino has 3 timers... timer0: pins 5 and 6 timer1: pins 9 and 10 timer2: pins 3 and 11 My Arduino Mega has 6 timers... timer0: pins 4, 13 timer1: pins 11, 12 timer2: pins 9, 10 timer3: pins 2, 3, 5 timer4: pins 6, 7, 8 timer5: pins 44, 45, 46 Because there are 6 "arms" of the snowflake, the normal Arduino clearly doesn't have enough PWM pins if the IRremote library is used! Only pins 5, 6, 9, and 10 are available. Either... (1) Set variable receiver to false (2) Connect arms 2 and 6 to the same pin and connect arms 3 and 5 to the same pin. This will prevent the "spin sequence" after the song from working well, and removing that code is easy to do. The Arduino Mega is in a much better situation. It must simply avoid pins 9 and 10! (c) 2018 Bradley Knockel */ // set the pin numbers! int const pin1 = 2; int const pin2 = 4; int const pin3 = 5; int const pin4 = 7; int const pin5 = 8; int const pin6 = 11; // Are you using an IR receiver? bool const receiver = true; // code for IR receiver int const pin = A0; #include "IRremote.h" // https://www.arduinolibraries.info/libraries/i-rremote IRrecv irrecv(pin); // create instance of 'irrecv' decode_results results; // create instance of 'decode_results' bool wait; bool checkIR() { //Serial.print("IR checked "); //Serial.println(millis()); if (irrecv.decode(&results)) { // have we received an IR signal? //Serial.println(results.value, HEX); delay(1000); // allow user time to stop pressing button wait = true; irrecv.resume(); // receive the next value return true; } else { return false; } } void write1(int c) {analogWrite(pin1, c);} void write2(int c) {analogWrite(pin2, c);} void write3(int c) {analogWrite(pin3, c);} void write4(int c) {analogWrite(pin4, c);} void write5(int c) {analogWrite(pin5, c);} void write6(int c) {analogWrite(pin6, c);} void writeAll(int c) { analogWrite(pin1, c); analogWrite(pin2, c); analogWrite(pin3, c); analogWrite(pin4, c); analogWrite(pin5, c); analogWrite(pin6, c); } void writeRow2(int c) { analogWrite(pin2, c); analogWrite(pin6, c); } void writeRow3(int c) { analogWrite(pin3, c); analogWrite(pin5, c); } void setup() { pinMode(pin1, OUTPUT); pinMode(pin2, OUTPUT); pinMode(pin3, OUTPUT); pinMode(pin4, OUTPUT); pinMode(pin5, OUTPUT); pinMode(pin6, OUTPUT); writeAll(0); // necessary? if (receiver) { wait = true; irrecv.enableIRIn(); // start the IR receiver (uses timer2) } else {wait = false;} Serial.begin(9600); } // timing a song can be tricky // so the only good way is to make frequent calls to millis() float timee; // keeping track of time in ms float const eighth=202.3; // ms for an eighth note float a; float b; float d; // for after the song, here's a number of ms // that is divisible by lots of things int const timme=216; //216 and 360 are good choices /* set some PWM stuff */ int const t=255; int const f=0; int const half = 16; // 2^4; between 0 and 255 // As decimal part of phase goes from 0.0 to 0.5, // brightness increases exponentially from 1 to 255 // As decimal part of phase goes from 0.5 to 1.0, // brightness decreases exponentially from 255 to 1 int brightness(float phase) { phase = phase - int(phase); if (phase<=0.5 && phase>=0.0) { return int(min(pow(2.,phase*16.0),255.0)); } else if (phase>0.5 && phase<=1.0) { return int(min(pow(2.,(1.0-phase)*16.0),255.0)); } else { return 0; // if phase is negative } } // As phase goes from 0.0 to 0.5, // brightness increases exponentially from 1 to 255 // As phase goes from 0.5 to 1.0, // brightness decreases exponentially from 255 to 1 int brightness2(float phase) { if (phase<=0.5 && phase>=0.0) { return int(min(pow(2.,phase*16.0),255.0)); } else if (phase>0.5 && phase<=1.0) { return int(min(pow(2.,(1.0-phase)*16.0),255.0)); } else { return 0; // if phase is negative or larger than 1.0 } } void blink(float c) { a=(c-millis())/2; writeAll(t); delay(c-a-millis()); writeAll(f); delay(c-millis()); } // Does not care about previous LED state. // Leaves 2,4 on void alternate(float c) { a=(c-millis())/2; write1(t); writeRow2(f); writeRow3(t); write4(f); delay(c-a-millis()); write1(f); writeRow2(t); writeRow3(f); write4(t); delay(c-millis()); } void towardsCenterA(float c) { a=(c-millis())/6; write1(half); delay(c-5*a-millis()); write1(t); delay(c-4*a-millis()); writeRow3(half); delay(c-3*a-millis()); write1(half); writeRow3(t); delay(c-2*a-millis()); write1(f); writeRow3(t); delay(c-a-millis()); writeRow3(half); delay(c-a/2-millis()); writeRow3(f); delay(c-millis()); } void towardsCenterB(float c) { a=(c-millis())/6; write4(half); delay(c-5*a-millis()); write4(t); delay(c-4*a-millis()); writeRow2(half); delay(c-3*a-millis()); write4(half); writeRow2(t); delay(c-2*a-millis()); write4(f); writeRow2(t); delay(c-a-millis()); writeRow2(half); delay(c-a/2-millis()); writeRow2(f); delay(c-millis()); } void towardsCenter(float c) { a=(c-millis())/6; write1(half); write4(half); delay(c-5*a-millis()); write1(t); write4(t); delay(c-4*a-millis()); writeRow2(half); writeRow3(half); delay(c-3*a-millis()); write1(half); write4(half); writeRow2(t); writeRow3(t); delay(c-2*a-millis()); write1(f); write4(f); writeRow2(t); writeRow3(t); delay(c-a-millis()); writeRow2(half); writeRow3(half); delay(c-a/2-millis()); writeRow2(f); writeRow3(f); delay(c-millis()); } void shrinkTowardsTop(float c) { a=(c-millis())/4; writeAll(t); delay(c-3*a-millis()); write4(f); delay(c-2*a-millis()); writeRow3(f); delay(c-a-millis()); writeRow2(f); delay(c-a/2-millis()); write1(f); delay(c-millis()); } int const updates = 50; // should be an even number void moveUpAndDown(float c) { a=(c-millis()); b=millis(); for (int i=1;i<=updates/2;i++) { d=0.5 + 1.5*(millis()-b)/a; write4(brightness2(d)); writeRow3(brightness2(d-1.0/4.0)); writeRow2(brightness2(d-2.0/4.0)); write1(brightness2(d-3.0/4.0)); delay(c - (updates-i)*a/updates - millis()); } for (int i=updates/2+1;i<=updates;i++) { d=0.5 + 1.5*(1.0-(millis()-b)/a); write4(brightness2(d)); writeRow3(brightness2(d-1.0/4.0)); writeRow2(brightness2(d-2.0/4.0)); write1(brightness2(d-3.0/4.0)); delay(c - (updates-i)*a/updates - millis()); } writeAll(f); } void neat(float c) { a=(c-millis()); b=millis(); for (int i=1;i<=updates/2;i++) { d=2.0*(millis()-b)/a; write4(brightness(d)); writeRow3(brightness(d+3.0/4.0)); writeRow2(brightness(d+2.0/4.0)); write1(brightness(d+1.0/4.0)); delay(c - (updates-i)*a/updates - millis()); } for (int i=updates/2+1;i<=updates;i++) { d=2.0 - 2.0*(millis()-b)/a; write4(brightness(d)); writeRow3(brightness(d+3.0/4.0)); writeRow2(brightness(d+2.0/4.0)); write1(brightness(d+1.0/4.0)); delay(c - (updates-i)*a/updates - millis()); } writeAll(f); } void moveFromCenter(float c) { a=(c-millis())/5; writeRow2(t); writeRow3(t); delay(c-3*a-millis()); writeRow2(f); writeRow3(f); write1(t); write4(t); delay(c-a-millis()); write1(f); write4(f); delay(c-millis()); } void moveFromCenter2(float c) { a=(c-millis())/4; writeAll(t); delay(c-3*a-millis()); write1(f); write4(f); delay(c-2*a-millis()); writeRow2(f); writeRow3(f); write1(t); write4(t); delay(c-a-millis()); write1(f); write4(f); delay(c-millis()); } // leaves all LEDs on void towardsCenter2(float c) { a=(c-millis())/5; write1(t); delay(c-4*a-millis()); write4(t); delay(c-3*a-millis()); writeRow2(t); delay(c-2*a-millis()); writeRow3(t); delay(c-millis()); } void flowUpwards(float c) { a=(c-millis())/4; write4(t); delay(c-3*a-millis()); write4(f); writeRow3(t); delay(c-2*a-millis()); writeRow3(f); writeRow2(t); delay(c-a-millis()); writeRow2(f); write1(t); delay(c-millis()); write1(f); } int const updates2 = 20; void flowUpwards2(float c) { a=(c-millis()); b=millis(); for (int i=1;i<=updates2;i++) { d=(millis()-b)/a; write4(brightness(d)); writeRow3(brightness(d+3.0/4.0)); writeRow2(brightness(d+2.0/4.0)); write1(brightness(d+1.0/4.0)); delay(c - (updates2-i)*a/updates2 - millis()); } writeAll(f); } // YouTube tree did this as moveFromCenter, // but I don't have enough LED sections void moveUpwards(float c) { a=(c-millis())/6; write4(t); delay(c-5*a-millis()); write4(f); writeRow3(t); delay(c-4*a-millis()); writeRow3(f); writeRow2(t); delay(c-2*a-millis()); writeRow2(f); write1(t); delay(c-millis()); write1(f); } // leaves all LEDs on void growUpwards(float c) { a=(c-millis())/4; write4(t); delay(c-3*a-millis()); writeRow3(t); delay(c-2*a-millis()); writeRow2(t); delay(c-a-millis()); write1(f); delay(c-millis()); } // leaves rows 1 and 3 lit void moveUpwardsDouble(float c) { a=(c-millis())/8; writeAll(t); delay(c-7*a-millis()); writeAll(f); write4(t); delay(c-6*a-millis()); write4(f); writeRow3(t); delay(c-4*a-millis()); writeRow3(f); write4(t); writeRow2(t); delay(c-2*a-millis()); writeRow2(f); write4(f); write1(t); writeRow3(t); delay(c-millis()); } void fallWithStyle(float c) { a=(c-millis())/4; write1(t); delay(c-3*a-millis()); write1(f); writeRow3(t); delay(c-2*a-millis()); writeRow3(f); writeRow2(t); delay(c-a-millis()); writeRow2(f); write4(t); delay(c-millis()); write4(f); } void spinCW(int a) { a=a/6; write1(t); delay(a); write1(f); write2(t); delay(a); write2(f); write3(t); delay(a); write3(f); write4(t); delay(a); write4(f); write5(t); delay(a); write5(f); write6(t); delay(a); write6(f); } // leaves all on void spinCW_on(int a) { a=a/6; write1(t); delay(a); write2(t); delay(a); write3(t); delay(a); write4(t); delay(a); write5(t); delay(a); write6(t); delay(a); } // Requires all to be on. // Leaves all on. void spinCW_dark(int a) { a=a/6; write1(f); delay(a); write1(t); write2(f); delay(a); write2(t); write3(f); delay(a); write3(t); write4(f); delay(a); write4(t); write5(f); delay(a); write5(t); write6(f); delay(a); write6(t); } // requires all to be on void spinCW_off(int a) { a=a/6; write1(f); delay(a); write2(f); delay(a); write3(f); delay(a); write4(f); delay(a); write5(f); delay(a); write6(f); delay(a); } void spinCCW(int a) { a=a/6; write1(t); delay(a); write1(f); write6(t); delay(a); write6(f); write5(t); delay(a); write5(f); write4(t); delay(a); write4(f); write3(t); delay(a); write3(f); write2(t); delay(a); write2(f); } // leaves all on void spinCCW_on(int a) { a=a/6; write1(t); delay(a); write6(t); delay(a); write5(t); delay(a); write4(t); delay(a); write3(t); delay(a); write2(t); delay(a); } // Requires all to be on. // Leaves all on. void spinCCW_dark(int a) { a=a/6; write1(f); delay(a); write1(t); write6(f); delay(a); write6(t); write5(f); delay(a); write5(t); write4(f); delay(a); write4(t); write3(f); delay(a); write3(t); write2(f); delay(a); write2(t); } // requires all to be on void spinCCW_off(int a) { a=a/6; write1(f); delay(a); write6(f); delay(a); write5(f); delay(a); write4(f); delay(a); write3(f); delay(a); write2(f); delay(a); } void spinOppCW(int a) { a=a/3; write1(t); write4(t); delay(a); write1(f); write4(f); write2(t); write5(t); delay(a); write2(f); write5(f); write3(t); write6(t); delay(a); write3(f); write6(f); } // leaves all on void spinOppCW_on(int a) { a=a/3; write1(t); write4(t); delay(a); write2(t); write5(t); delay(a); write3(t); write6(t); delay(a); } // Requires all to be on. // Leaves all on. void spinOppCW_dark(int a) { a=a/3; write1(f); write4(f); delay(a); write1(t); write4(t); write2(f); write5(f); delay(a); write2(t); write5(t); write3(f); write6(f); delay(a); write3(t); write6(t); } // requires all to be on void spinOppCW_off(int a) { a=a/3; write1(f); write4(f); delay(a); write2(f); write5(f); delay(a); write3(f); write6(f); delay(a); } void spinOppCCW(int a) { a=a/3; write1(t); write4(t); delay(a); write1(f); write4(f); write3(t); write6(t); delay(a); write3(f); write6(f); write2(t); write5(t); delay(a); write2(f); write5(f); } // leaves all on void spinOppCCW_on(int a) { a=a/3; write1(t); write4(t); delay(a); write3(t); write6(t); delay(a); write2(t); write5(t); delay(a); } // Requires all to be on. // Leaves all on. void spinOppCCW_dark(int a) { a=a/3; write1(f); write4(f); delay(a); write1(t); write4(t); write3(f); write6(f); delay(a); write3(t); write6(t); write2(f); write5(f); delay(a); write2(t); write5(t); } // requires all to be on void spinOppCCW_off(int a) { a=a/3; write1(f); write4(f); delay(a); write3(f); write6(f); delay(a); write2(f); write5(f); delay(a); } void spinDoubleCW(int a) { a=a/3; write1(t); write2(t); delay(a); write1(f); write2(f); write3(t); write4(t); delay(a); write3(f); write4(f); write5(t); write6(t); delay(a); write5(f); write6(f); } void spinDoubleCCW(int a) { a=a/3; write1(t); write6(t); delay(a); write1(f); write6(f); write5(t); write4(t); delay(a); write5(f); write4(f); write2(t); write3(t); delay(a); write2(f); write3(f); } void spinDouble2CW(int a) { a=a/6; write6(t); write1(t); delay(a); write6(f); write2(t); delay(a); write1(f); write3(t); delay(a); write2(f); write4(t); delay(a); write3(f); write5(t); delay(a); write4(f); write6(t); delay(a); write5(f); write6(f); } void spinDouble2CCW(int a) { a=a/6; write2(t); write1(t); delay(a); write2(f); write6(t); delay(a); write1(f); write5(t); delay(a); write6(f); write4(t); delay(a); write5(f); write3(t); delay(a); write4(f); write2(t); delay(a); write2(f); write3(f); } void spinTripleCW(int a) { a=a/6; write5(t); write6(t); write1(t); delay(a); write5(f); write2(t); delay(a); write6(f); write3(t); delay(a); write1(f); write4(t); delay(a); write2(f); write5(t); delay(a); write3(f); write6(t); delay(a); write4(f); write5(f); write6(f); } void spinTripleCCW(int a) { a=a/6; write3(t); write2(t); write1(t); delay(a); write3(f); write6(t); delay(a); write2(f); write5(t); delay(a); write1(f); write4(t); delay(a); write6(f); write3(t); delay(a); write5(f); write2(t); delay(a); write2(f); write3(f); write4(f); } // leaves all LEDs on void spinFinishCW(int a) { a=a/12; write4(t); write5(t); write6(t); write1(t); delay(a); write4(f); write2(t); delay(a); write5(f); write3(t); delay(a); write6(f); write4(t); delay(a); write1(f); write5(t); delay(a); write2(f); write6(t); delay(a); write1(t); // now doing 5 at a time delay(a); write3(f); write2(t); delay(a); write4(f); write3(t); delay(a); write5(f); write4(t); delay(a); write6(f); write5(t); delay(a); write1(f); write6(t); delay(a); write1(t); } void blink0(int a) { a=a/2; writeAll(t); delay(a); writeAll(f); delay(a); } // Does not care about previous LED state. // Leaves 2,4,6 on void alternate1(int a) { a=a/2; write1(t); write2(f); write3(t); write4(f); write5(t); write6(f); delay(a); write1(f); write2(t); write3(f); write4(t); write5(f); write6(t); delay(a); } // Does not care about previous LED state. // Leaves 3,5 on, and maybe 1,4 if they were on previously. // Looks like wings! void alternate2(int a) { a=a/2; write2(t); write3(f); write5(f); write6(t); delay(a); write2(f); write3(t); write5(t); write6(f); delay(a); } // Does not care about previous LED state. // Leaves 3,6 on, and maybe 1,4 if they were on previously. // Looks like a seesaw! void alternate3(int a) { a=a/2; write2(t); write3(f); write5(t); write6(f); delay(a); write2(f); write3(t); write5(f); write6(t); delay(a); } // Does not care about previous LED state. // Leaves 3,6 on, and maybe 1,4 if they were on previously. // Goes left to right! void alternate4(int a) { a=a/2; write2(f); write3(f); write5(t); write6(t); delay(a); write2(t); write3(t); write5(f); write6(f); delay(a); } void loop() { while(true) { // allows "break;" to "reset" the code while (wait) { if (irrecv.decode(&results)) { // have we received an IR signal? wait = false; //Serial.println(results.value, HEX); } } // // the following test takes 15 ms (negligible) //int j=0; //Serial.println(millis()); //for(int i=0;i<10000;i++){ // j=j+millis(); //} //Serial.println(millis()); //delay(4900); // for syncing up with YouTube video timee = millis(); towardsCenterA(timee += eighth*3*8); irrecv.resume(); // receive the next IR value shrinkTowardsTop(timee += eighth*8); towardsCenterB(timee += eighth*3*8); shrinkTowardsTop(timee += eighth*8); if(checkIR()){break;} moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); shrinkTowardsTop(timee += eighth*8); if(checkIR()){break;} moveUpAndDown(timee += eighth*4); // at measure 13 moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); blink(timee += eighth*2); timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); if(checkIR()){break;} blink(timee += eighth*2); timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); blink(timee += eighth*2); // start measure 18 timee += eighth;delay(timee-millis()); alternate(timee += eighth*2); timee += eighth*2;delay(timee-millis()); alternate(timee += eighth*2); timee += eighth;delay(timee-millis()); alternate(timee += eighth*4); write1(t);writeRow2(f);writeRow3(t);write4(f);timee += eighth;delay(timee-millis()); writeAll(f);timee += eighth;delay(eighth); if(checkIR()){break;} moveUpAndDown(timee += eighth*4); // start measure 20 moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); blink(timee += eighth*2); timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); if(checkIR()){break;} moveUpAndDown(timee += eighth*4); // start measure 24 moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); blink(timee += eighth*2); timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); if(checkIR()){break;} blink(timee += eighth*2); //start measure 28 timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); blink(timee += eighth*2); // start measure 29 timee += eighth;delay(timee-millis()); alternate(timee += eighth*2); timee += eighth*2;delay(timee-millis()); write1(t);writeRow2(f);writeRow3(t);write4(f);timee += eighth;delay(timee-millis()); if(checkIR()){break;} shrinkTowardsTop(timee += eighth*16); // measures 30 and 31 if(checkIR()){break;} // measures 32, 33, 34, 35 flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); flowUpwards(timee += eighth*2); if(checkIR()){break;} // 1:02 in the YouTube video timee += eighth*2;delay(timee-millis()); moveUpwards(timee += eighth*6); timee += eighth*2;delay(timee-millis()); moveUpwards(timee += eighth*6); timee += eighth*2;delay(timee-millis()); moveUpwards(timee += eighth*6); flowUpwards(timee += eighth*8); // measure 39 if(checkIR()){break;} timee += eighth*2;delay(timee-millis()); moveUpwards(timee += eighth*6); timee += eighth*2;delay(timee-millis()); moveUpwards(timee += eighth*6); timee += eighth*2;delay(timee-millis()); moveUpwards(timee += eighth*6); flowUpwards(timee += eighth*8); // measure 43 if(checkIR()){break;} blink(timee += eighth*2); timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); blink(timee += eighth*2); timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); blink(timee += eighth*2); // start measure 46 timee += eighth;delay(timee-millis()); alternate(timee += eighth*2); timee += eighth*2;delay(timee-millis()); alternate(timee += eighth*2); timee += eighth;delay(timee-millis()); alternate(timee += eighth*4); write1(t);writeRow2(f);writeRow3(t);write4(f);timee += eighth;delay(timee-millis()); writeAll(f);timee += eighth;delay(timee-millis()); if(checkIR()){break;} moveUpAndDown(timee += eighth*4); // start measure 48 moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); shrinkTowardsTop(timee += eighth*8); if(checkIR()){break;} moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); blink(timee += eighth*2); timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); // end at 1:34 in YouTube if(checkIR()){break;} blink(timee += eighth*2); //start measure 56 timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); blink(timee += eighth*2); // start measure 57 timee += eighth;delay(timee-millis()); towardsCenter2(timee += eighth*5); shrinkTowardsTop(timee += eighth*16); // measures 58 and 59 if(checkIR()){break;} growUpwards(timee += eighth*8); //measure 60 shrinkTowardsTop(timee += eighth*8); //measure 61 if(checkIR()){break;} for(int i=0;i<32;i++){ blink(timee += eighth*1); blink(timee += eighth*2); blink(timee += eighth*1); } if(checkIR()){break;} // at measure 78 (at 2:10 in YouTube video) blink(timee += eighth*2); timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); blink(timee += eighth*2); timee += eighth;delay(timee-millis()); moveFromCenter(timee += eighth*5); blink(timee += eighth*2); // start measure 80 timee += eighth;delay(timee-millis()); alternate(timee += eighth*2); timee += eighth*2;delay(timee-millis()); alternate(timee += eighth*2); timee += eighth;delay(timee-millis()); alternate(timee += eighth*4); write1(t);writeRow2(f);writeRow3(t);write4(f);timee += eighth;delay(timee-millis()); writeAll(f);timee += eighth;delay(timee-millis()); if(checkIR()){break;} moveUpAndDown(timee += eighth*4); // start measure 82 moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); shrinkTowardsTop(timee += eighth*8); if(checkIR()){break;} moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); if(checkIR()){break;} moveUpwardsDouble(timee += eighth*8); // measure 89 (at 2:28 in YouTube video) writeRow2(t);write4(t);timee += eighth*2;delay(timee-millis()); // measure 90 alternate(timee += eighth*2); alternate(timee += eighth*2); alternate(timee += eighth*2); writeRow3(t);write1(t);timee += eighth/2;delay(timee-millis()); // start measure 91 write1(f);writeRow2(t);writeRow3(f);write4(t);timee += eighth/2;delay(timee-millis()); alternate(timee += eighth); alternate(timee += eighth); alternate(timee += eighth); writeRow3(t);write1(t);timee += eighth/2;delay(timee-millis()); write1(f);writeRow2(t);writeRow3(f);write4(t);timee += eighth/2;delay(timee-millis()); alternate(timee += eighth); alternate(timee += eighth); alternate(timee += eighth); blink(timee += eighth*2); // start measure 92 blink(timee += eighth*2); blink(timee += eighth*2); shrinkTowardsTop(timee += eighth*2); if(checkIR()){break;} //measures 93,94,95,96,97,98,99,100 for(int i=0;i<8;i++){ moveUpAndDown(timee += eighth*4); moveUpAndDown(timee += eighth*4); if(checkIR()){break;} } // at 2:47 in YouTube video fallWithStyle(timee += eighth*4); fallWithStyle(timee += eighth*4); fallWithStyle(timee += eighth*4); fallWithStyle(timee += eighth*4); if(checkIR()){break;} for(int i=0;i<4;i++){ blink(timee += eighth); blink(timee += eighth); blink(timee += eighth); blink(timee += eighth); blink(timee += eighth); blink(timee += eighth); blink(timee += eighth); blink(timee += eighth); } if(checkIR()){break;} // at measure 107 (at 2:57 in YouTube video) shrinkTowardsTop(timee += eighth*4); moveFromCenter2(timee += eighth*4); moveUpwardsDouble(timee += eighth*4); blink(timee += eighth*2); alternate(timee += eighth*2); shrinkTowardsTop(timee += eighth*4); moveFromCenter2(timee += eighth*4); moveUpwardsDouble(timee += eighth*4); blink(timee += eighth*2); alternate(timee += eighth*2); // I guess the sheet sheet music leaves out 2 measures! if(checkIR()){break;} // measures 109 and 110 of sheet music flowUpwards2(timee += eighth*2); flowUpwards2(timee += eighth*2); flowUpwards2(timee += eighth*2); flowUpwards2(timee += eighth*2); flowUpwards2(timee += eighth*2); flowUpwards2(timee += eighth*2); flowUpwards2(timee += eighth*2); flowUpwards2(timee += eighth*2); if(checkIR()){break;} // measure 111 of sheet music blink(timee += eighth*4); while(true){ delay(5000); if(checkIR()){break;} spinSequence(); // takes a while! if(checkIR()){break;} delay(5000); if(checkIR()){break;} // below are unused functions that are really neat! towardsCenter(millis()+24*eighth); neat(millis()+4*eighth); neat(millis()+4*eighth); neat(millis()+4*eighth); neat(millis()+4*eighth); neat(millis()+4*eighth); neat(millis()+4*eighth); if(checkIR()){break;} } } } void spinSequence() { spinCW(timme); spinCW(timme); delay(timme); spinCCW(timme); spinCCW(timme); delay(timme); spinCW_on(timme); spinCW_dark(timme); spinCW_dark(timme); spinCW_dark(timme); spinCW_off(timme); delay(timme); spinCCW_on(timme); spinCCW_dark(timme); spinCCW_dark(timme); spinCCW_dark(timme); spinCCW_off(timme); delay(timme); spinCW(timme); spinCCW(timme); spinCW(timme); spinCCW(timme); delay(timme*2); spinOppCW(timme); spinOppCW(timme); delay(timme); spinOppCCW(timme); spinOppCCW(timme); delay(timme); spinOppCW_on(timme); spinOppCW_dark(timme); spinOppCW_dark(timme); spinOppCW_dark(timme); spinOppCW_off(timme); delay(timme); spinOppCCW_on(timme); spinOppCCW_dark(timme); spinOppCCW_dark(timme); spinOppCCW_dark(timme); spinOppCCW_off(timme); delay(timme); spinOppCW(timme); spinOppCCW(timme); spinOppCW(timme); spinOppCCW(timme); delay(timme*2); spinDoubleCW(timme*2); spinDoubleCW(timme*2); spinDoubleCW(timme*2); delay(timme*2); spinDoubleCCW(timme*2); spinDoubleCCW(timme*2); spinDoubleCCW(timme*2); delay(timme*2); spinDouble2CW(timme*2); spinDouble2CW(timme*2); spinDouble2CW(timme*2); delay(timme*2); spinDouble2CCW(timme*2); spinDouble2CCW(timme*2); spinDouble2CCW(timme*2); delay(timme*2); spinTripleCW(timme*2); spinTripleCW(timme*2); spinTripleCW(timme*2); delay(timme*2); spinTripleCCW(timme*2); spinTripleCCW(timme*2); spinTripleCCW(timme*2); delay(timme*2); // neat! spinCW(timme); spinDouble2CW(timme); spinTripleCW(timme); spinFinishCW(timme*2); delay(timme*2); writeAll(f); delay(timme*2); // wings alternate2(timme); alternate2(timme); writeAll(f); delay(timme); // seesaw alternate3(timme); alternate3(timme); writeAll(f); delay(timme); // left to right alternate4(timme); alternate4(timme); writeAll(f); delay(timme); alternate1(timme); alternate1(timme); writeAll(t); delay(timme*4); spinCW_dark(timme*2); spinCCW_dark(timme*2); spinCW_dark(timme*2); spinCCW_dark(timme*2); delay(timme*2); alternate2(timme*2); alternate2(timme*2); alternate2(timme*2); alternate2(timme*2); alternate2(timme*2); alternate2(timme*2); writeAll(t); delay(timme*2); alternate1(timme); alternate1(timme); writeAll(f); delay(timme*4); blink0(timme); blink0(timme); }