ProtonPack

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 152acffa01bc33a3d8ef9e46c118e51478c3a295
parent 39e0fbebcebb75a93533c7dd8efcb1444fca7edf
Author: Samdal <samdal@protonmail.com>
Date:   Tue,  7 Nov 2023 15:47:06 +0100

imporv

Diffstat:
Msrc/main.cpp | 363++++++++++++++++++++++++++++++++++++++++---------------------------------------
1 file changed, 182 insertions(+), 181 deletions(-)

diff --git a/src/main.cpp b/src/main.cpp @@ -17,7 +17,7 @@ #define SHOOTING_TIME 20000 #define IDLE_TIME 550000 -#define DEBUGGING 1 +#define DEBUGGING 0 // front potentiometer is the potentiometer on the gun // it is used to change the proton hp directly above @@ -34,11 +34,22 @@ #define INTENSIFY_FRONT A13 // lower button on the left side, starts the shootign animation #define INTENSIFY A14 +// motor that vibrates the neutrino wand +#define VIBRATOR 8 // output for the high power led, AKA the proton beam #define HP_LED_R 9 #define HP_LED_G 10 #define HP_LED_B 11 +enum { + PROTON_ACCELERATOR, + DARK_MATTER_GENERATOR, + PLASM_DISTRIBUTION_SYSTEM, + COMPOSITE_PARTICLE_SYSTEM, + PROTON_MODES_COUNT, +} proton_modes; +int current_mode = PROTON_ACCELERATOR; + // cyclotron fade time #define CYCLOTRON_FADE_TIME 10 #define CYCLOTRON_FADE_AMOUNT 5 @@ -54,15 +65,49 @@ enum { #define PACK_LEDS_PIN 13 CRGB pack_leds[PACK_NUM_LEDS]; +const CRGB cyclotron_colors[PROTON_MODES_COUNT] = { + CRGB::Red, + CRGB::Blue, + CRGB::Green, + CRGB::DarkOrange, +}; +#define SET_CYCLOTRON_ON(_led) pack_leds[_led] = cyclotron_colors[current_mode] + enum { - VENT_LED, + GUN_ON_LED, WHITE_LED, + VENT_LED, FRONT_LED, GUN_NUM_LEDS, } gun_leds_names; #define GUN_LEDS_PIN 12 CRGB gun_leds[GUN_NUM_LEDS]; +const CRGB gun_led_colors[PROTON_MODES_COUNT][GUN_NUM_LEDS] = { + { + CRGB::Red, + CRGB::White, + CRGB::White, + CRGB::OrangeRed, + }, { + CRGB::Red, + CRGB::White, + CRGB::Blue, + CRGB::OrangeRed, + }, { + CRGB::Red, + CRGB::White, + CRGB::Green, + CRGB::OrangeRed, + }, { + CRGB::Red, + CRGB::White, + CRGB::Yellow, + CRGB::OrangeRed, + }, +}; +#define SET_GUN_LED_ON(_led) gun_leds[_led] = gun_led_colors[current_mode][_led] + enum { power_down_sound = 1, pack_hum_sound, @@ -76,15 +121,6 @@ enum { #define PACK_VOLUME 30 DFPlayerMini_Fast myMP3; -enum { - PROTON_ACCELERATOR, - DARK_MATTER_GENERATOR, - PLASM_DISTRIBUTION_SYSTEM, - COMPOSITE_PARTICLE_SYSTEM, - PROTON_MODES_COUNT, -} proton_modes; -int current_mode = PROTON_ACCELERATOR; - #define PROTON_GRAPH_COUNT 10 const uint8_t proton_graph[PROTON_GRAPH_COUNT] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; uint8_t proton_graph_stage = 0; @@ -94,14 +130,15 @@ const int powercell[POWERCELL_COUNT] {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42 uint8_t powercell_stage = 0; // button variables (stored here so that debug mode can change them) -bool gun_power_on = true; bool pack_power_on = true; +bool gun_power_on; bool proton_indicator_on; bool activate_on; bool intensify_on; bool intensify_reload; bool front_led_on = true; +bool vent_led_on = true; bool shooting; bool system_on; @@ -119,14 +156,11 @@ int red_state = 0; int green_state = 0; int blue_state = 0; -#define MAX_POWER 100 -#define HIGH_POWER_LED_DELAY 2 - // colors of the firing beam uint8_t high_power_led_colors[PROTON_MODES_COUNT][4][3] = { { // PROTON_ACCELERATOR // red, yellow, white, blue - {90, 0, 0}, {70 , 60, 0}, {90 , 80, 80}, {7 , 20, 70} + {255, 0, 0}, {100 , 210, 0}, {255, 255, 255}, {50 , 30, 200} }, { // DARK_MATTER_GENERATOR // blue, white, light blue, purple @@ -163,16 +197,15 @@ void run_powercell(); void powercell_off(); // changes brightness in the led at the end of the gun accordingly -bool high_power_led(const uint8_t* ledcolor, const unsigned long spacing_delay); +bool high_power_led(const uint8_t* ledcolor, const unsigned long spacing_delay, bool no_fade); void high_power_led_off(); +bool start_vent(bool reset = false); void pulse_led(); // pulses the WHITE_LED inversely with the FRONT_LED void run_proton_indicator(); void read_potentiometer(); void proton_indicator_off(); -CRGB vent_color(); -CRGB cyclotron_color(); void run_cyclotron(); void fade_cyclotron(); void cyclotron_off(); @@ -205,6 +238,7 @@ void setup() pinMode(HP_LED_R, OUTPUT); pinMode(HP_LED_G, OUTPUT); pinMode(HP_LED_B, OUTPUT); + pinMode(VIBRATOR, OUTPUT); // neopixel leds FastLED.addLeds<NEOPIXEL, PACK_LEDS_PIN>(pack_leds, PACK_NUM_LEDS); @@ -216,9 +250,7 @@ void setup() // sound Serial1.begin(9600); myMP3.begin(Serial1); - delay(500); - myMP3.volume(PACK_VOLUME); - delay(500); + delay(100); } @@ -230,7 +262,6 @@ void loop() //debugging_message(); #else gun_power_on = digitalRead(GUN_POWER); - pack_power_on = digitalRead(PACK_POWER); #endif t = millis(); @@ -261,6 +292,7 @@ void run_proton_pack() run_cyclotron(); run_powercell(); reduce_proton_hp(); + FastLED.show(); } // reads the potentiometer at the front and writes a value to proton_hp @@ -283,14 +315,15 @@ void start_up() for (int i = 0; i < POWERCELL_COUNT; i++) digitalWrite(powercell[i], HIGH); - for (int i = 0; i < 100; i++) { + // TODO make it fade towards selected mdoes target color + for (int i = 0; i < 255; i++) { pack_leds[CYCLOTRON1].setRGB(i, 0, 0); pack_leds[CYCLOTRON2].setRGB(i, 0, 0); pack_leds[CYCLOTRON3].setRGB(i, 0, 0); pack_leds[CYCLOTRON4].setRGB(i, 0, 0); FastLED.show(); - delay(17); + delay(10); } reset_pack(); } @@ -298,6 +331,7 @@ void start_up() // check the gun switches and act accordingly void run_proton_gun() { + SET_GUN_LED_ON(GUN_ON_LED); // if debugging mode is on, dont read switches // the buttons are set from the serial monitor // see debugging_switches() @@ -315,24 +349,27 @@ void run_proton_gun() if (activate_on) { pulse_led(); - gun_leds[VENT_LED] = vent_color(); - FastLED.show(); + if(vent_led_on) vent_led_on = start_vent(); + static unsigned long last_shot; if (intensify_on) { - shoot(); + if (t - last_shot > 500) + shoot(); } else if (shooting) { + last_shot = t; myMP3.play(gun_trail_sound); shooting = false; high_power_led_off(); + digitalWrite(VIBRATOR, LOW); } } else { // do theese if the proton indicator is on but not the generator switch front_led_on = true; gun_leds[VENT_LED] = CRGB::Black; + vent_led_on = true; gun_leds[FRONT_LED] = CRGB::Black; - gun_leds[WHITE_LED] = CRGB::White; - FastLED.show(); + SET_GUN_LED_ON(WHITE_LED); } if (intensify_reload) { @@ -344,8 +381,8 @@ void run_proton_gun() gun_leds[VENT_LED] = CRGB::Black; gun_leds[FRONT_LED] = CRGB::Black; gun_leds[WHITE_LED] = CRGB::Black; - FastLED.show(); proton_reduction = 0; + vent_led_on = true; proton_indicator_off(); } } @@ -393,9 +430,7 @@ void run_cyclotron() // if the cyclotron is off, turn it on after a time has exceeded. if (!cyclotron_on && t - cyclotron_previous_time >= proton_pack_time) { - pack_leds[cyclotron_stage] = cyclotron_color(); - FastLED.show(); - + SET_CYCLOTRON_ON(cyclotron_stage); cyclotron_previous_time = t; cyclotron_on = true; } @@ -410,20 +445,21 @@ void reload(bool overheat) #endif myMP3.play(gun_overheat_sound); - pack_leds[CYCLOTRON1] = cyclotron_color(); - pack_leds[CYCLOTRON2] = cyclotron_color(); - pack_leds[CYCLOTRON3] = cyclotron_color(); - pack_leds[CYCLOTRON4] = cyclotron_color(); + SET_CYCLOTRON_ON(CYCLOTRON1); + SET_CYCLOTRON_ON(CYCLOTRON2); + SET_CYCLOTRON_ON(CYCLOTRON3); + SET_CYCLOTRON_ON(CYCLOTRON4); proton_indicator_off(); for (int i = 0; i < POWERCELL_COUNT; i++) digitalWrite(powercell[i], HIGH); high_power_led_off(); + digitalWrite(VIBRATOR, LOW); pack_leds[N_FILTER] = CRGB::Red; - gun_leds[WHITE_LED] = CRGB::White; - gun_leds[FRONT_LED] = CRGB::Red; - gun_leds[VENT_LED] = vent_color(); + SET_GUN_LED_ON(WHITE_LED); + SET_GUN_LED_ON(FRONT_LED); + SET_GUN_LED_ON(VENT_LED); FastLED.show(); if (overheat) { delay(OVERHEAT_TIME); @@ -466,7 +502,7 @@ void reduce_proton_hp() } // if there is less than x hp left, play the overheat warning sound - if (proton_hp - proton_reduction <= 12 && !beeped) { + if (proton_hp - proton_reduction <= 10 && !beeped) { beeped = true; if (shooting) myMP3.play(beep_shoot_sound); else myMP3.play(beep_sound); @@ -483,20 +519,28 @@ void reduce_proton_hp() gun_leds[WHITE_LED] = CRGB::Black; gun_leds[VENT_LED] = CRGB::Black; FastLED.show(); - delay(200); + + unsigned long time_now = millis(); + while (millis() - time_now < 200) { + run_proton_gun(); + } proton_indicator_off(); powercell_off(); - pack_leds[CYCLOTRON1] = cyclotron_color(); - pack_leds[CYCLOTRON2] = cyclotron_color(); - pack_leds[CYCLOTRON3] = cyclotron_color(); - pack_leds[CYCLOTRON4] = cyclotron_color(); + SET_CYCLOTRON_ON(CYCLOTRON1); + SET_CYCLOTRON_ON(CYCLOTRON2); + SET_CYCLOTRON_ON(CYCLOTRON3); + SET_CYCLOTRON_ON(CYCLOTRON4); pack_leds[N_FILTER] = CRGB::Black; - gun_leds[FRONT_LED] = CRGB::Red; - gun_leds[WHITE_LED] = CRGB::White; - gun_leds[VENT_LED] = CRGB::White; + SET_GUN_LED_ON(VENT_LED); + SET_GUN_LED_ON(FRONT_LED); + SET_GUN_LED_ON(WHITE_LED); FastLED.show(); - delay(200); + + time_now = millis(); + while (millis() - time_now < 200) { + run_proton_gun(); + } } } else if (proton_hp - proton_reduction > 12 && beeped){ beeped = false; @@ -506,58 +550,52 @@ void reduce_proton_hp() // shoot and depleet amunition void shoot() { - static unsigned long previous_led_update = 0; // letting the program know it has shot so that when it turns of it can play the trail effect if (!shooting) { shooting = true; myMP3.play(shoot_sound); + digitalWrite(VIBRATOR, HIGH); } - if (t - previous_led_update >= HIGH_POWER_LED_DELAY) { - static bool color_change; - static unsigned long rng_delay = 100; - static int rng; - - if (color_change) { - rng = random(10); - rng_delay = random(100, 300); - color_change = false; - } - - switch (rng) { - - // 4/10 chance of being color 1 - case 0: - case 1: - case 2: - case 3: - color_change = high_power_led(high_power_led_colors[current_mode][0], rng_delay); - break; - - // 3/10 chance of being color 2 - case 4: - case 5: - case 6: - color_change = high_power_led(high_power_led_colors[current_mode][1], rng_delay); - break; - - // 2/10 chance of being color 3 - case 7: - case 8: - color_change = high_power_led(high_power_led_colors[current_mode][2], rng_delay); - break; - - // 1/10 chance of being color 4 - case 9: - color_change = high_power_led(high_power_led_colors[current_mode][3], rng_delay); - break; - default: - color_change = true; - break; - } - previous_led_update = t; - } - + static bool color_change; + static unsigned long rng_delay = 100; + static int rng; + static bool no_fade; + + if (color_change) { + static bool no_fade_next; + rng = random(10); + rng_delay = random(80, 200); + if (no_fade_next) { + no_fade_next = false; + no_fade = false; + } else { + if (no_fade) no_fade_next = true; + else no_fade = random(2) && rng_delay < 150; + } + color_change = false; + } + + switch (rng) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + color_change = high_power_led(high_power_led_colors[current_mode][0], rng_delay + 100, no_fade); + break; + case 7: + color_change = high_power_led(high_power_led_colors[current_mode][1], rng_delay, no_fade); + break; + case 8: + color_change = high_power_led(high_power_led_colors[current_mode][2], rng_delay, no_fade); + break; + case 9: + color_change = high_power_led(high_power_led_colors[current_mode][3], rng_delay, no_fade); + break; + } // reduce the proton_hp (ammonution) static unsigned long last_shooting; @@ -567,28 +605,33 @@ void shoot() } } +#define red_max 90 // changes brightness in the led at the end of the gun accordingly -bool high_power_led(const uint8_t* ledcolor, const unsigned long spacing_delay) +bool high_power_led(const uint8_t* ledcolor, const unsigned long spacing_delay, bool no_fade) { static unsigned long previous_color_change; - int R = constrain(ledcolor[0], 0, MAX_POWER); + int R = min(ledcolor[0], red_max); + int G = ledcolor[1]; + int B = ledcolor[2]; + if (no_fade) { + red_state = R; + green_state = G; + blue_state = B; + } + if (red_state < R) red_state++; else if (red_state > R) red_state--; - int G = constrain(ledcolor[1], 0, MAX_POWER); if (green_state < G) green_state++; else if (green_state > G) green_state--; - int B = constrain(ledcolor[2], 0, MAX_POWER); if (blue_state < B) blue_state++; else if (blue_state > B) blue_state--; - analogWrite(HP_LED_R, red_state); analogWrite(HP_LED_G, green_state); analogWrite(HP_LED_B, blue_state); - if (red_state == R && green_state == G && blue_state == B - && t - previous_color_change >= spacing_delay) { + if (t - previous_color_change >= spacing_delay) { previous_color_change = t; return true; } @@ -609,13 +652,17 @@ void gun_lights_off() { proton_reduction = 0; front_led_on = true; + vent_led_on = true; + start_vent(true); - gun_leds[WHITE_LED] = CRGB::Black; - gun_leds[FRONT_LED] = CRGB::Black; - gun_leds[VENT_LED] = CRGB::Black; + gun_leds[GUN_ON_LED] = CRGB::Black; + gun_leds[WHITE_LED] = CRGB::Black; + gun_leds[FRONT_LED] = CRGB::Black; + gun_leds[VENT_LED] = CRGB::Black; FastLED.show(); high_power_led_off(); + digitalWrite(VIBRATOR, LOW); proton_indicator_off(); if (shooting) { @@ -630,20 +677,44 @@ void gun_lights_off() void pulse_led() { static unsigned long previous_pulse; - if (t - previous_pulse >= proton_pack_time / 1.5) { + if (t - previous_pulse >= proton_pack_time) { if (front_led_on) { - gun_leds[WHITE_LED] = CRGB::White; + SET_GUN_LED_ON(WHITE_LED); gun_leds[FRONT_LED] = CRGB::Black; } else { gun_leds[WHITE_LED] = CRGB::Black; - gun_leds[FRONT_LED] = CRGB::Red; + SET_GUN_LED_ON(FRONT_LED); } - FastLED.show(); front_led_on = !front_led_on; previous_pulse = t; } } +#define vent_blink_time 60 +bool start_vent(bool reset) { + static unsigned long last_vent_blink; + static int vent_times; + static bool vent_on; + + if (vent_times > 4 || reset) { + if (!reset) SET_GUN_LED_ON(VENT_LED); + vent_times = 0; + return false; + } + if (millis() - last_vent_blink < vent_blink_time) + return true; + + if (vent_on) + gun_leds[VENT_LED] = CRGB::Black; + else + SET_GUN_LED_ON(VENT_LED); + + vent_on = !vent_on; + last_vent_blink = millis(); + vent_times++; + return true; +} + void run_proton_indicator() { proton_graph_stage = (proton_hp - proton_reduction) / (DEFAULT_PROTON_HP / 10); @@ -659,29 +730,6 @@ void proton_indicator_off() digitalWrite(proton_graph[i], LOW); } -CRGB cyclotron_color() -{ - switch (current_mode) { - case PROTON_ACCELERATOR: return CRGB::Red; - case DARK_MATTER_GENERATOR: return CRGB::Blue; - case PLASM_DISTRIBUTION_SYSTEM: return CRGB::Green; - case COMPOSITE_PARTICLE_SYSTEM: return CRGB::Orange; - default: return CRGB::White; - } -} - -// changes the color of the vent -CRGB vent_color() -{ - switch (current_mode) { - case PROTON_ACCELERATOR: return CRGB::White; - case DARK_MATTER_GENERATOR: return CRGB::Blue; - case PLASM_DISTRIBUTION_SYSTEM: return CRGB::Green; - case COMPOSITE_PARTICLE_SYSTEM: return CRGB::Yellow; - default: return CRGB::Red; - } -} - void cyclotron_off() { pack_leds[CYCLOTRON1] = CRGB::Black; @@ -689,8 +737,6 @@ void cyclotron_off() pack_leds[CYCLOTRON3] = CRGB::Black; pack_leds[CYCLOTRON4] = CRGB::Black; FastLED.show(); - - cyclotron_stage = 3; } void fade_cyclotron() @@ -709,51 +755,6 @@ void fade_cyclotron() pack_leds[i].raw[c] = 0; } cyclotron_previous_fade = t; - FastLED.show(); -} - -// printing debugging messages -void debugging_message() -{ - delay(200); - for (int i = 0 ; i < 30 ; i++) { - Serial.println(""); - } - - if (!system_on) { - Serial.println("System is off"); - return; - } - Serial.println("Switches:"); - Serial.println("gun_power_on: " + String(gun_power_on)); - Serial.println("pack_power_on: " + String(pack_power_on)); - Serial.println("proton_indicator_on: " + String(proton_indicator_on)); - Serial.println("activate_on: " + String(activate_on)); - Serial.println("intensify_on: " + String(intensify_on)); - Serial.println("intensify_reload: " + String(intensify_reload)); - Serial.println(""); - - Serial.println("Proton HP: " + String(proton_hp)); - Serial.println("Effective proton HP: " + String(proton_hp - proton_reduction)); - Serial.println("t: " + String(t)); - Serial.println("Proton pack mode: " + String(current_mode)); - Serial.println(); - Serial.println("Cyclotron stage: " + String(cyclotron_stage)); - Serial.println("Powercell stage: " + String(powercell_stage)); - - if (!gun_power_on) return; - - Serial.println(""); - Serial.println("Gun lights:"); - Serial.println("White led: " + String(!front_led_on)); - Serial.println("front led: " + String(front_led_on)); - Serial.println("Vent led: " + String(activate_on)); - Serial.println("Proton indicator stage: " + String(proton_graph_stage)); - Serial.println("Proton position: " + String(proton_indicator_pot_value)); - Serial.println("Proton reduction: " + String(proton_reduction)); - Serial.println(""); - Serial.println("Shooting: " + String(shooting)); - } // turning on and off switches from Serial monitor