main.cpp (22938B)
1 #include <Arduino.h> 2 3 #include <FastLED.h> 4 #include <DFPlayerMini_Fast.h> 5 6 // time it takes to reload when overheated 7 // if not overheatign reloading takes half the time 8 #define OVERHEAT_TIME 5000 9 10 // default "hp" 11 // this value represents how long it is until 12 // the pack overheats and is slowly depleted 13 // over time or via shooting 14 #define DEFAULT_PROTON_HP 100 15 16 #define DEFAULT_PROTON_PACK_TIME 600 17 #define SHOOTING_TIME 20000 18 #define IDLE_TIME 550000 19 20 #define DEBUGGING 0 21 22 // front potentiometer is the potentiometer on the gun 23 // it is used to change the proton hp directly above 24 // a cretan threshold 25 #define FRONT_POTENTIOMETER A8 26 #define PACK_POWER A9 27 // lower button on the right side 28 #define GUN_POWER A10 29 // upper button on the right side 30 #define PROTON_INDICATOR A11 31 // upper button on the left side 32 #define ACTIVATE A12 33 // button on the front of the gun 34 #define INTENSIFY_FRONT A13 35 // lower button on the left side, starts the shootign animation 36 #define INTENSIFY A14 37 // motor that vibrates the neutrino wand 38 #define VIBRATOR 8 39 // output for the high power led, AKA the proton beam 40 #define HP_LED_R 9 41 #define HP_LED_G 10 42 #define HP_LED_B 11 43 44 enum { 45 PROTON_ACCELERATOR, 46 DARK_MATTER_GENERATOR, 47 PLASM_DISTRIBUTION_SYSTEM, 48 COMPOSITE_PARTICLE_SYSTEM, 49 PROTON_MODES_COUNT, 50 } proton_modes; 51 int current_mode = PROTON_ACCELERATOR; 52 53 // cyclotron fade time 54 #define CYCLOTRON_FADE_TIME 10 55 #define CYCLOTRON_FADE_AMOUNT 5 56 57 enum { 58 CYCLOTRON1, 59 CYCLOTRON2, 60 CYCLOTRON3, 61 CYCLOTRON4, 62 N_FILTER, 63 PACK_NUM_LEDS, 64 } pack_leds_names; 65 #define PACK_LEDS_PIN 13 66 CRGB pack_leds[PACK_NUM_LEDS]; 67 68 const CRGB cyclotron_colors[PROTON_MODES_COUNT] = { 69 CRGB::Red, 70 CRGB::Blue, 71 CRGB::Green, 72 CRGB::DarkOrange, 73 }; 74 #define SET_CYCLOTRON_ON(_led) pack_leds[_led] = cyclotron_colors[current_mode] 75 76 enum { 77 GUN_ON_LED, 78 WHITE_LED, 79 VENT_LED, 80 FRONT_LED, 81 GUN_NUM_LEDS, 82 } gun_leds_names; 83 #define GUN_LEDS_PIN 12 84 CRGB gun_leds[GUN_NUM_LEDS]; 85 86 const CRGB gun_led_colors[PROTON_MODES_COUNT][GUN_NUM_LEDS] = { 87 { 88 CRGB::Red, 89 CRGB::White, 90 CRGB::White, 91 CRGB::OrangeRed, 92 }, { 93 CRGB::Red, 94 CRGB::White, 95 CRGB::Blue, 96 CRGB::OrangeRed, 97 }, { 98 CRGB::Red, 99 CRGB::White, 100 CRGB::Green, 101 CRGB::OrangeRed, 102 }, { 103 CRGB::Red, 104 CRGB::White, 105 CRGB::Yellow, 106 CRGB::OrangeRed, 107 }, 108 }; 109 #define SET_GUN_LED_ON(_led) gun_leds[_led] = gun_led_colors[current_mode][_led] 110 111 #define JRGEN_EXTRA 112 113 #ifdef JRGEN_EXTRA 114 enum { 115 power_down_sound = 1, 116 pack_hum_sound, 117 gun_trail_sound, 118 start_up_sound, 119 beep_sound, 120 beep_shoot_sound, 121 gun_overheat_sound, 122 shoot_sound, 123 ghostbusters_theme_song, 124 } tracks; 125 #else 126 enum { 127 power_down_sound = 1, 128 pack_hum_sound, 129 gun_trail_sound, 130 start_up_sound, 131 beep_sound, 132 beep_shoot_sound, 133 gun_overheat_sound, 134 } trakcs; 135 #endif 136 137 #define PACK_VOLUME 30 138 DFPlayerMini_Fast myMP3; 139 140 #define PROTON_GRAPH_COUNT 10 141 const uint8_t proton_graph[PROTON_GRAPH_COUNT] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; 142 uint8_t proton_graph_stage = 0; 143 144 #define POWERCELL_COUNT 20 145 const int powercell[POWERCELL_COUNT] {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51}; 146 uint8_t powercell_stage = 0; 147 148 // button variables (stored here so that debug mode can change them) 149 bool pack_power_on = true; 150 bool gun_power_on; 151 bool proton_indicator_on; 152 bool activate_on; 153 bool intensify_on; 154 bool intensify_reload; 155 156 bool front_led_on = true; 157 bool vent_led_on = true; 158 bool shooting; 159 bool system_on; 160 161 // current proton reduction caused by the proton indicator knob 162 int proton_reduction; 163 uint8_t proton_indicator_pot_value = 5; 164 165 uint8_t cyclotron_stage; 166 167 uint8_t proton_hp = DEFAULT_PROTON_HP; 168 169 // state of the high power led 170 // for smooth transition 171 int red_state = 0; 172 int green_state = 0; 173 int blue_state = 0; 174 175 // colors of the firing beam 176 uint8_t high_power_led_colors[PROTON_MODES_COUNT][4][3] = { 177 { // PROTON_ACCELERATOR 178 // red-orange, blue, yellow, white 179 {255, 130, 0}, {20 , 20, 255}, {255 , 180, 0}, {255, 200, 230}, 180 }, 181 { // DARK_MATTER_GENERATOR 182 // blue, white, light blue, purple 183 {0 , 0, 90}, {80 , 80, 90}, {0 , 30, 70}, {60 , 0, 80} 184 }, 185 { // PLASM_DISTRIBUTION_SYSTEM 186 // green, light green, green, white 187 {0, 90, 0}, {20, 90, 10}, {0, 90, 0}, {80 , 90, 80} 188 }, 189 { // COMPOSITE_PARTICLE_SYSTEM 190 // yellow, orange, red, white 191 {70 , 60, 0}, {80 , 60, 5}, {90, 0, 0}, {90 , 80, 80} 192 } 193 }; 194 195 196 // time in between cyclotron changes 197 // incereeses depending on the proton hp 198 unsigned long proton_pack_time = DEFAULT_PROTON_PACK_TIME / 100 * proton_hp; 199 200 // global time value to run the different timings 201 unsigned long t = 0; 202 203 void start_up(); 204 void run_proton_pack(); 205 void reduce_proton_hp(); 206 void run_proton_gun(); 207 void gun_lights_off(); 208 void shoot(); 209 void reload(bool overheat); 210 void reset_pack(); 211 212 void run_powercell(); 213 void powercell_off(); 214 215 // changes brightness in the led at the end of the gun accordingly 216 bool high_power_led(const uint8_t* ledcolor, const unsigned long spacing_delay, bool no_fade); 217 void high_power_led_off(); 218 219 bool start_vent(bool reset = false); 220 void pulse_led(); // pulses the WHITE_LED inversely with the FRONT_LED 221 void run_proton_indicator(); 222 void read_potentiometer(); 223 void proton_indicator_off(); 224 225 void run_cyclotron(); 226 void fade_cyclotron(); 227 void cyclotron_off(); 228 229 void debugging_message(); 230 void debugging_switches(); 231 232 void setup() 233 { 234 #if DEBUGGING 235 Serial.begin(115200); 236 Serial.println("Debug mode entered"); 237 delay(1000); 238 #endif 239 240 // input pins (buttons and switches) 241 pinMode(PACK_POWER, INPUT); 242 pinMode(GUN_POWER, INPUT); 243 pinMode(PROTON_INDICATOR, INPUT); 244 pinMode(ACTIVATE, INPUT); 245 pinMode(INTENSIFY, INPUT); 246 pinMode(INTENSIFY_FRONT, INPUT); 247 248 // output pins 249 for (int i = 0; i < PROTON_GRAPH_COUNT; i++) 250 pinMode(proton_graph[i], OUTPUT); 251 for (int i = 0; i < POWERCELL_COUNT; i++) 252 pinMode(powercell[i], OUTPUT); 253 254 pinMode(HP_LED_R, OUTPUT); 255 pinMode(HP_LED_G, OUTPUT); 256 pinMode(HP_LED_B, OUTPUT); 257 pinMode(VIBRATOR, OUTPUT); 258 259 // neopixel leds 260 FastLED.addLeds<NEOPIXEL, PACK_LEDS_PIN>(pack_leds, PACK_NUM_LEDS); 261 FastLED.addLeds<NEOPIXEL, GUN_LEDS_PIN>(gun_leds, GUN_NUM_LEDS); 262 FastLED.clear(true); 263 cyclotron_off(); 264 gun_lights_off(); 265 266 // sound 267 Serial1.begin(9600); 268 myMP3.begin(Serial1); 269 delay(100); 270 } 271 272 273 // loop while the arduino has power 274 void loop() 275 { 276 #if DEBUGGING 277 debugging_switches(); 278 //debugging_message(); 279 #else 280 gun_power_on = digitalRead(GUN_POWER); 281 #endif 282 t = millis(); 283 284 if (pack_power_on || gun_power_on) { 285 if (!system_on) { 286 start_up(); 287 system_on = true; 288 } 289 290 if (gun_power_on) run_proton_gun(); 291 else gun_lights_off(); 292 293 run_proton_pack(); 294 } 295 if (!pack_power_on && !gun_power_on && system_on) { 296 myMP3.play(power_down_sound); 297 reset_pack(); 298 system_on = false; 299 delay(100); 300 } 301 } 302 303 // turn on / keep running the proton pack lights 304 void run_proton_pack() 305 { 306 proton_pack_time = DEFAULT_PROTON_PACK_TIME / DEFAULT_PROTON_HP * ( proton_hp - proton_reduction ) + 40; 307 308 run_cyclotron(); 309 run_powercell(); 310 reduce_proton_hp(); 311 FastLED.show(); 312 } 313 314 // reads the potentiometer at the front and writes a value to proton_hp 315 void read_potentiometer() 316 { 317 #if !DEBUGGING 318 proton_indicator_pot_value = map(analogRead(FRONT_POTENTIOMETER), 0, 1023, 0, 5); 319 #endif 320 if (proton_indicator_pot_value == 5) proton_indicator_pot_value = 4; 321 322 if (proton_indicator_pot_value == 0) proton_reduction = DEFAULT_PROTON_HP - 20; 323 else proton_reduction = DEFAULT_PROTON_HP - (proton_indicator_pot_value + 1) * 20; 324 } 325 326 // animation and sound when the proton pack starts 327 void start_up() 328 { 329 myMP3.play(start_up_sound); 330 331 for (int i = 0; i < POWERCELL_COUNT; i++) 332 digitalWrite(powercell[i], HIGH); 333 334 // TODO make it fade towards selected mdoes target color 335 for (int i = 0; i < 255; i++) { 336 pack_leds[CYCLOTRON1].setRGB(i, 0, 0); 337 pack_leds[CYCLOTRON2].setRGB(i, 0, 0); 338 pack_leds[CYCLOTRON3].setRGB(i, 0, 0); 339 pack_leds[CYCLOTRON4].setRGB(i, 0, 0); 340 FastLED.show(); 341 342 delay(10); 343 } 344 reset_pack(); 345 } 346 347 // check the gun switches and act accordingly 348 void run_proton_gun() 349 { 350 SET_GUN_LED_ON(GUN_ON_LED); 351 // if debugging mode is on, dont read switches 352 // the buttons are set from the serial monitor 353 // see debugging_switches() 354 static bool last_intensify_reload_state; 355 last_intensify_reload_state = intensify_reload; 356 #if !DEBUGGING 357 // check the gun switches 358 proton_indicator_on = digitalRead(PROTON_INDICATOR); 359 activate_on = digitalRead(ACTIVATE); 360 intensify_on = digitalRead(INTENSIFY); 361 intensify_reload = digitalRead(INTENSIFY_FRONT); 362 #endif 363 364 if (proton_indicator_on) { 365 read_potentiometer(); 366 run_proton_indicator(); 367 368 if (activate_on) { 369 pulse_led(); 370 if(vent_led_on) vent_led_on = start_vent(); 371 372 static unsigned long last_shot; 373 if (intensify_on) { 374 if (t - last_shot > 500) 375 shoot(); 376 } else if (shooting) { 377 last_shot = t; 378 myMP3.play(gun_trail_sound); 379 shooting = false; 380 high_power_led_off(); 381 digitalWrite(VIBRATOR, LOW); 382 } 383 if (intensify_reload) { 384 shooting = false; 385 reload(false); 386 return; 387 } 388 } else { 389 // do theese if the proton indicator is on but not the generator switch 390 front_led_on = true; 391 gun_leds[VENT_LED] = CRGB::Black; 392 vent_led_on = true; 393 gun_leds[FRONT_LED] = CRGB::Black; 394 SET_GUN_LED_ON(WHITE_LED); 395 396 if (intensify_reload && !last_intensify_reload_state) { 397 static bool is_on = false; 398 is_on = !is_on; 399 #ifdef JRGEN_EXTRA 400 if (is_on) 401 myMP3.play(ghostbusters_theme_song); 402 else 403 myMP3.stop(); 404 #endif 405 } 406 } 407 } else { 408 gun_leds[VENT_LED] = CRGB::Black; 409 gun_leds[FRONT_LED] = CRGB::Black; 410 gun_leds[WHITE_LED] = CRGB::Black; 411 proton_reduction = 0; 412 vent_led_on = true; 413 proton_indicator_off(); 414 } 415 } 416 417 void powercell_off() 418 { 419 for (int i = 0; i < POWERCELL_COUNT; i++) 420 digitalWrite(powercell[i], LOW); 421 powercell_stage = 0; 422 } 423 424 void run_powercell() 425 { 426 static unsigned long powercell_previous_time; 427 428 if (t - powercell_previous_time >= proton_pack_time / 6) { 429 if (powercell_stage >= POWERCELL_COUNT) { 430 for (int i = 0; i < POWERCELL_COUNT; i++) 431 digitalWrite(powercell[i], LOW); 432 powercell_stage = 0; 433 } else { 434 digitalWrite(powercell[powercell_stage++], HIGH); 435 } 436 437 powercell_previous_time = t; 438 } 439 } 440 441 void run_cyclotron() 442 { 443 static unsigned long cyclotron_previous_time; 444 static bool cyclotron_on; 445 446 fade_cyclotron(); 447 448 // while the cyclotron is on, it should stay on for a set amount of time 449 if (cyclotron_on && t - cyclotron_previous_time >= proton_pack_time / 3 * 2) { 450 cyclotron_stage++; 451 cyclotron_previous_time = t; 452 cyclotron_on = false; 453 } 454 455 // loop around 456 if (cyclotron_stage > 3) cyclotron_stage = 0; 457 458 // if the cyclotron is off, turn it on after a time has exceeded. 459 if (!cyclotron_on && t - cyclotron_previous_time >= proton_pack_time) { 460 SET_CYCLOTRON_ON(cyclotron_stage); 461 cyclotron_previous_time = t; 462 cyclotron_on = true; 463 } 464 } 465 466 // reloads (sound and light animations), if overheated it lasts longer 467 void reload(bool overheat) 468 { 469 #if DEBUGGING 470 Serial.println("---------!RELOADING!---------"); 471 if (overheat) Serial.println("---------!OVERHEATED!---------"); 472 #endif 473 myMP3.play(gun_overheat_sound); 474 475 SET_CYCLOTRON_ON(CYCLOTRON1); 476 SET_CYCLOTRON_ON(CYCLOTRON2); 477 SET_CYCLOTRON_ON(CYCLOTRON3); 478 SET_CYCLOTRON_ON(CYCLOTRON4); 479 proton_indicator_off(); 480 for (int i = 0; i < POWERCELL_COUNT; i++) 481 digitalWrite(powercell[i], HIGH); 482 high_power_led_off(); 483 digitalWrite(VIBRATOR, LOW); 484 485 pack_leds[N_FILTER] = CRGB::White; 486 487 SET_GUN_LED_ON(WHITE_LED); 488 SET_GUN_LED_ON(FRONT_LED); 489 SET_GUN_LED_ON(VENT_LED); 490 FastLED.show(); 491 if (overheat) { 492 delay(OVERHEAT_TIME); 493 } else { 494 delay(OVERHEAT_TIME / 2); 495 intensify_reload = false; 496 } 497 reset_pack(); 498 start_up(); 499 } 500 501 // resets variables and resets functions 502 void reset_pack() 503 { 504 gun_lights_off(); 505 FastLED.clear(true); 506 FastLED.show(); 507 508 proton_hp = DEFAULT_PROTON_HP; 509 cyclotron_off(); 510 powercell_off(); 511 } 512 513 // reduces the proton_hp (ammonution) accordingly 514 void reduce_proton_hp() 515 { 516 static unsigned long previous_hp_reduction; 517 static bool beeped; 518 519 // automaticaly reload if the proton hp is a zero 520 if (proton_hp - proton_reduction <= 0) { 521 reload(true); 522 return; 523 } 524 525 // reduce the proton_hp slowly while the pack is ideling (does not apply if there isn't any proton reduction) 526 if (proton_reduction != 0 && t - previous_hp_reduction >= IDLE_TIME / DEFAULT_PROTON_HP) { 527 proton_hp -= 1; 528 previous_hp_reduction = t; 529 } 530 531 // if there is less than x hp left, play the overheat warning sound 532 if (proton_hp - proton_reduction <= 10 && !beeped) { 533 beeped = true; 534 if (shooting) myMP3.play(beep_shoot_sound); 535 else myMP3.play(beep_sound); 536 537 for (uint8_t blinkamount = 0; blinkamount <= 5; blinkamount++) { 538 for (int i = 0; i < PROTON_GRAPH_COUNT; i++) 539 digitalWrite(proton_graph[i], HIGH); 540 for (int i = 0; i < POWERCELL_COUNT; i++) 541 digitalWrite(powercell[i], HIGH); 542 543 cyclotron_off(); 544 pack_leds[N_FILTER] = CRGB::White; 545 gun_leds[FRONT_LED] = CRGB::Black; 546 gun_leds[WHITE_LED] = CRGB::Black; 547 gun_leds[VENT_LED] = CRGB::Black; 548 FastLED.show(); 549 550 unsigned long time_now = millis(); 551 while (millis() - time_now < 200) { 552 run_proton_gun(); 553 } 554 555 proton_indicator_off(); 556 powercell_off(); 557 SET_CYCLOTRON_ON(CYCLOTRON1); 558 SET_CYCLOTRON_ON(CYCLOTRON2); 559 SET_CYCLOTRON_ON(CYCLOTRON3); 560 SET_CYCLOTRON_ON(CYCLOTRON4); 561 pack_leds[N_FILTER] = CRGB::Black; 562 SET_GUN_LED_ON(VENT_LED); 563 SET_GUN_LED_ON(FRONT_LED); 564 SET_GUN_LED_ON(WHITE_LED); 565 FastLED.show(); 566 567 time_now = millis(); 568 while (millis() - time_now < 200) { 569 run_proton_gun(); 570 } 571 } 572 } else if (proton_hp - proton_reduction > 12 && beeped){ 573 beeped = false; 574 } 575 } 576 577 // shoot and depleet amunition 578 void shoot() 579 { 580 // letting the program know it has shot so that when it turns of it can play the trail effect 581 if (!shooting) { 582 shooting = true; 583 myMP3.play(shoot_sound); 584 digitalWrite(VIBRATOR, HIGH); 585 } 586 587 static bool color_change; 588 static unsigned long rng_delay = 100; 589 static int rng; 590 static bool no_fade; 591 592 if (color_change) { 593 static bool no_fade_next; 594 rng = random(10); 595 rng_delay = random(80, 200); 596 if (no_fade_next) { 597 no_fade_next = false; 598 no_fade = false; 599 } else { 600 if (no_fade) no_fade_next = true; 601 else no_fade = random(2) && rng_delay < 150; 602 } 603 color_change = false; 604 } 605 606 switch (rng) { 607 case 0: 608 case 1: 609 case 2: 610 case 3: 611 color_change = high_power_led(high_power_led_colors[current_mode][0], rng_delay + 60, no_fade); 612 break; 613 case 4: 614 case 5: 615 case 6: 616 color_change = high_power_led(high_power_led_colors[current_mode][1], rng_delay, no_fade); 617 break; 618 case 7: 619 case 8: 620 color_change = high_power_led(high_power_led_colors[current_mode][2], rng_delay, no_fade); 621 break; 622 case 9: 623 color_change = high_power_led(high_power_led_colors[current_mode][3], rng_delay, no_fade); 624 break; 625 } 626 627 // reduce the proton_hp (ammonution) 628 static unsigned long last_shooting; 629 if (t - last_shooting >= SHOOTING_TIME / DEFAULT_PROTON_HP) { 630 proton_hp -= 1; 631 last_shooting = t; 632 } 633 } 634 635 #define red_max 90 636 // changes brightness in the led at the end of the gun accordingly 637 bool high_power_led(const uint8_t* ledcolor, const unsigned long spacing_delay, bool no_fade) 638 { 639 static unsigned long previous_color_change; 640 int R = min(ledcolor[0], red_max); 641 int G = ledcolor[1]; 642 int B = ledcolor[2]; 643 if (no_fade) { 644 red_state = R; 645 green_state = G; 646 blue_state = B; 647 } 648 649 if (red_state < R) red_state++; 650 else if (red_state > R) red_state--; 651 652 #ifdef JRGEN_EXTRA 653 if (green_state < G) green_state++; 654 else if (green_state > G) green_state--; 655 #else 656 green_state = G; 657 #endif 658 659 if (blue_state < B) blue_state++; 660 else if (blue_state > B) blue_state--; 661 662 analogWrite(HP_LED_R, red_state); 663 analogWrite(HP_LED_G, green_state); 664 analogWrite(HP_LED_B, blue_state); 665 if (t - previous_color_change >= spacing_delay) { 666 previous_color_change = t; 667 return true; 668 } 669 return false; 670 } 671 672 void high_power_led_off() 673 { 674 analogWrite(HP_LED_R, 0); 675 analogWrite(HP_LED_G, 0); 676 analogWrite(HP_LED_B, 0); 677 red_state = 0; 678 green_state = 0; 679 blue_state = 0; 680 } 681 682 void gun_lights_off() 683 { 684 proton_reduction = 0; 685 front_led_on = true; 686 vent_led_on = true; 687 start_vent(true); 688 689 gun_leds[GUN_ON_LED] = CRGB::Black; 690 gun_leds[WHITE_LED] = CRGB::Black; 691 gun_leds[FRONT_LED] = CRGB::Black; 692 gun_leds[VENT_LED] = CRGB::Black; 693 FastLED.show(); 694 695 high_power_led_off(); 696 digitalWrite(VIBRATOR, LOW); 697 proton_indicator_off(); 698 699 if (shooting) { 700 delay(100); 701 myMP3.play(gun_trail_sound); 702 shooting = false; 703 } 704 } 705 706 707 // pulses the WHITE_LED inversely with the FRONT_LED 708 void pulse_led() 709 { 710 static unsigned long previous_pulse; 711 if (t - previous_pulse >= proton_pack_time) { 712 if (front_led_on) { 713 SET_GUN_LED_ON(WHITE_LED); 714 gun_leds[FRONT_LED] = CRGB::Black; 715 } else { 716 gun_leds[WHITE_LED] = CRGB::Black; 717 SET_GUN_LED_ON(FRONT_LED); 718 } 719 front_led_on = !front_led_on; 720 previous_pulse = t; 721 } 722 } 723 724 #define vent_blink_time 60 725 bool start_vent(bool reset) { 726 static unsigned long last_vent_blink; 727 static int vent_times; 728 static bool vent_on; 729 730 if (vent_times > 4 || reset) { 731 if (!reset) SET_GUN_LED_ON(VENT_LED); 732 vent_times = 0; 733 return false; 734 } 735 if (millis() - last_vent_blink < vent_blink_time) 736 return true; 737 738 if (vent_on) 739 gun_leds[VENT_LED] = CRGB::Black; 740 else 741 SET_GUN_LED_ON(VENT_LED); 742 743 vent_on = !vent_on; 744 last_vent_blink = millis(); 745 vent_times++; 746 return true; 747 } 748 749 void run_proton_indicator() 750 { 751 proton_graph_stage = (proton_hp - proton_reduction) / (DEFAULT_PROTON_HP / 10); 752 for (int i = 0; i < PROTON_GRAPH_COUNT; i++) { 753 if (i <= proton_graph_stage) digitalWrite(proton_graph[i], HIGH); 754 else digitalWrite(proton_graph[i], LOW); 755 } 756 } 757 758 void proton_indicator_off() 759 { 760 for (int i = 0; i < PROTON_GRAPH_COUNT; i++) 761 digitalWrite(proton_graph[i], LOW); 762 } 763 764 void cyclotron_off() 765 { 766 pack_leds[CYCLOTRON1] = CRGB::Black; 767 pack_leds[CYCLOTRON2] = CRGB::Black; 768 pack_leds[CYCLOTRON3] = CRGB::Black; 769 pack_leds[CYCLOTRON4] = CRGB::Black; 770 FastLED.show(); 771 } 772 773 void fade_cyclotron() 774 { 775 static unsigned long cyclotron_previous_fade; 776 if(t - cyclotron_previous_fade < CYCLOTRON_FADE_TIME) return; 777 778 for(int i = 0; i < 4; i++) { 779 if (i == cyclotron_stage) continue; 780 781 // cycle down r, g and b values 782 for(int c = 0; c < 3; c++) 783 if (pack_leds[i].raw[c] >= CYCLOTRON_FADE_AMOUNT) 784 pack_leds[i].raw[c] -= CYCLOTRON_FADE_AMOUNT; 785 else 786 pack_leds[i].raw[c] = 0; 787 } 788 cyclotron_previous_fade = t; 789 } 790 791 // turning on and off switches from Serial monitor 792 void debugging_switches() 793 { 794 if (Serial.available()) { 795 switch(Serial.read()) { 796 case 'g': gun_power_on = !gun_power_on; break; 797 case 'p': pack_power_on = !pack_power_on; break; 798 case 'q': proton_indicator_on = !proton_indicator_on; break; 799 case 'a': activate_on = !activate_on; break; 800 case 'i': intensify_on = !intensify_on; break; 801 case 'r': intensify_reload = !intensify_reload; break; 802 803 case '0': proton_indicator_pot_value = 0; break; 804 case '1': proton_indicator_pot_value = 1; break; 805 case '2': proton_indicator_pot_value = 2; break; 806 case '3': proton_indicator_pot_value = 3; break; 807 case '4': proton_indicator_pot_value = 4; break; 808 case '5': proton_indicator_pot_value = 5; break; 809 } 810 } 811 }