Guest User

Black Betty HPA Nerf Blaster Electronic Fire Control Unit

a guest
Nov 22nd, 2018
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* BLACK BETTY HPA NERF BLASTER Electronic Fire Control Group source code V0.1
  2.  
  3.     Original code by DaXLR 2018/11
  4.  
  5.     This code is free to use and modify under an Attribution/Non-commercial CC license
  6.  
  7.     As I commented the code I noticed a bunch of pretty bad practices and sub-optimal stuff, but I'm too lazy to fix it for now. This code works and is (mostly) readable. Might change it later
  8.  
  9.     Be safe and have fun!
  10. */
  11.  
  12.  
  13. int  solenoid = 2; //Output pin for solenoid
  14. int trigger = 11; //Input pin for trigger microswitch
  15. int safety = 9; //Input pin for saftey logic signal
  16. int fullauto = 7; //Input pin for full auto logic signal
  17. int dwell = 75; //Time in ms that the system is going to keep air going to the piston to push the BCG forward, more dwell time means more reliable cycling but less time to charge the reservoir between shots (so less power)
  18. int cooldown = 200; //Time in ms between shots. Used for both full and semi-auto. Less cooldown means faster fire rate, but less time to charge the reservoir between shots (so less power)
  19. int antibounce = 15; //Time in ms that the trigger needs to be held down to register as a shot. Used to prevent accidental triggers from the blaster cycling.
  20. unsigned long currentmillis = 0; //Used for global timings (see the BlinkWithoutDelay tutorial on Arduino to understand how this works)
  21. unsigned long previouscooldown = 0; //Notes the last time a cooldown period has started
  22. unsigned long previousdwell = 0; //Notes the last time a dwell period has started
  23. int shotqueue = 0; //Keeps track of if the system should fire or not
  24. int firemode = 0; //Keeps track of the firemode, 0 is safe, 1 is semi, 2 is full
  25. int waitforrelease = 0; //Flag to wait for the trigger release in semi-auto
  26.  
  27. void setup() {
  28.  
  29.   Serial.begin(9600);
  30.  
  31.   //Setting pinmodes
  32.  
  33.   pinMode(safety, INPUT);
  34.   pinMode(fullauto, INPUT);
  35.   pinMode(solenoid, OUTPUT);
  36.   pinMode(trigger, INPUT);
  37.   pinMode(13, OUTPUT);
  38. }
  39.  
  40. void loop() {
  41.  
  42.   //Looking for current fire selector position
  43.   if (digitalRead(safety)) {
  44.     firemode = 0;
  45.   }
  46.   else if (digitalRead(fullauto)) {
  47.     firemode = 2;
  48.   }
  49.   else {
  50.     firemode = 1; //If the fire selector is broken or absent, this is the default firemode that<s going to be used
  51.   }
  52.  
  53.   //Semi auto mode
  54.  
  55.   if (firemode == 1) {
  56.  
  57.     if (digitalRead(trigger) && waitforrelease == 0) { //Wait for release is only equals to 0 as the trigger is released. This means that this code is only ever going to run once per trigger press since the flag is set to true within it.
  58.       delay(antibounce);
  59.       if (digitalRead(trigger)) {
  60.         waitforrelease = 1; //Sets the flag to ignore the trigger until released
  61.         shotqueue = 1; //Sets the flag for the shooting code to actually fire
  62.       }
  63.  
  64.     }
  65.     else if (!digitalRead(trigger)) {
  66.       waitforrelease = 0; //Resets the flag if trigger is released
  67.     }
  68.  
  69.     //Firing code
  70.  
  71.     currentmillis = millis();
  72.     if (currentmillis >= previouscooldown + cooldown) { //The code is only ever going to chech for the firing flag if the system is outside of its cooldown period
  73.       if (shotqueue >= 1) {
  74.         Serial.println("Shot Fired");
  75.         digitalWrite(solenoid, HIGH);
  76.         digitalWrite(13, HIGH); //Pin 13 on the metro mini is the onboard LED, useful for a quick indicator.
  77.         previousdwell = millis(); //Tells the code to start counting dwell time from here
  78.         previouscooldown = millis(); //Tells the code to start counting cooldown from here
  79.         shotqueue = 0; //Resets the firing flag
  80.       }
  81.     }
  82.     // Code to check if dwell time has elapsed
  83.     currentmillis = millis();
  84.     if (millis() >= previousdwell + dwell) {
  85.       digitalWrite(solenoid, LOW);
  86.       digitalWrite(13, LOW);
  87.     }
  88.   }
  89.  
  90.   //Full auto, same code as semi-auto, except you dont need the waitforrelease flag.
  91.   if (firemode == 2) {
  92.  
  93.     if (shotqueue <= 0) {
  94.       shotqueue = 0;
  95.     }
  96.     if (shotqueue >= 1) {
  97.       shotqueue = 1;
  98.     }
  99.     if (digitalRead(trigger)) {
  100.       shotqueue = 1;
  101.     }
  102.     else if (!digitalRead(trigger)) {
  103.       shotqueue = 0;
  104.     }
  105.  
  106.     currentmillis = millis();
  107.     if (currentmillis >= previouscooldown + cooldown) {
  108.       if (shotqueue >= 1) {
  109.         Serial.println("Shot Fired");
  110.         digitalWrite(solenoid, HIGH);
  111.         digitalWrite(13, HIGH);
  112.         previousdwell = millis();
  113.         previouscooldown = millis();
  114.         shotqueue = 0;
  115.       }
  116.     }
  117.     currentmillis = millis();
  118.     if (millis() >= previousdwell + dwell) {
  119.       digitalWrite(solenoid, LOW);
  120.       digitalWrite(13, LOW);
  121.     }
  122.   }
  123. }
Add Comment
Please, Sign In to add comment