Arduino - Airsoft ASCU


Sections on this page:
Download the code.
Step by step code walk through.
See how to upload the code.


In this guide I will walk you through how the arduino code of the AirsoftTech.dk DIY - Burst mode Mosfet works. So if you have not seen the hardware guide then you should start by clicking the link and see what this is all about.

Code walk through:
First a small note on comments: When eaver you find 2 slashes then the rest of the line is ignored by the arduino, and the text is only there to help you read the code. Each comment say somthing about what the code does to help you understand the code.
In this walk through i don't include the comments because I explain each line in the code.
int MOSFET_PIN = 5;
int TRIGGER_PIN = A0;

The first 2 lines of code shown here above (int MOSFET_ etc...) is global code, so here we set up things that the hole program needs to know. The first line tells the code that the MOSFET gate will be connected to digital pin 5 (also called D5 on the arduino nano board). The second line tells that the triggr controll wire will be attached (through a voltage divider) to the A0 pin.

The mosfet gate is what is used to open and close the mosfet switch. Think of the mosfet gate as a kind of light switch, when a voltage is applied to the gate, then the mosfet opens and electricity can flow from drain to source. When the voltage is removed the mosfet is turned off and the connection is broken.
int Max_ON_Time = 200;

This line of code tells the arduino how long the gun takes to shoot 3 shots. You may need to ajust this value depending on how fast the gun shoots. The value is given in milliseconds (Thoudsands of seconds) so 1000 would be 1 second. If you already know your gun's rate of fire ROF you can calculate what this value should be. You do that with this formula: 1000 / ROF * 3 Shots. Eg. 20 rounds per second would give 1000 / 20 = 50 * 3 = 150. So the value should be 150 or maby a bit above.
int TrigerStatus = LOW;
int TriggerReadValue = 0;
int CurrentSleepTime = 0;

The 3 above lines of code is internal values that the arduino uses. The "TrigerStatus" value is the status of the trigger of the gun. LOW means that it is not pressed, and HIGH would mean the trigger is pressed. To start off with we assume the trigger is not pulled = LOW.

When you use a battery, Eg. 11.1V lipo, the voltage needs to be lowered to a safe level that the arduino can handle. !!A maximum of 5 volts may be given!!. So we feed the trigger input through a voltage divider, lowering the value to below 5 volts. But the value is acturaly lowered to much just to be safe (So we can handle batteries of higher voltage levels). An 11.1v lipo will give a 1v input, and a 7.4v would give 0.673 volts, so digital pins would not register this input. There for we use an analog pin (A0 stands for Analog pin 0) that reads from 0 to 5 volts (where 5 volts would give a value of 1023, 2.5v would give 512 and so forth). So the 7.4 volt lipo's input of 0.673 would give an input value of: 1023/5*0.673 = 138. The "TriggerReadValue" is the value that is read from the analog input pin. In the 7.4v example TriggerReadValue would become 138.

The "CurrentSleepTime" is how long the arduino has been waiting for the 3 shot's to have been fired. So when pressing the trigger this value will increace untill it reaches the "Max_ON_Time" described above.
void setup() 
{
  pinMode(13, OUTPUT);
  pinMode(MOSFET_PIN, OUTPUT);
  digitalWrite(MOSFET_PIN, LOW);
  digitalWrite(13, LOW);
}

When the arduino starts the setup function runs once. Meaning that each line from the "{" character down to the "}" will run. The 2 first lines starting with pinMode tells the arduino if we plan on using the pins as OUTPUT or as INPUT. Pin 13 is the small LED that is mounted on the Arduino nano, and setting pinMode 13 to OUTPUT means that we can command the LED to be on or off (HIGH or LOW). In the same way we tell that the MOSFET_PIN (defigned in the beginning as pin 5) will also be an OUTPUT from the arduino. Because we want to set the voltage level going from pin D5 to the Mosfet Gate pin. So now we can turn on / off the mosfet by setting the value of the MOSFET_PIN.
After setting the pin 13 and MOSFET_PIN to OUTPUT, we assign them values with digitalWrite. We assign them both as LOW so that the Mosfet is turned of and the motor won't start up, and the LED is turned off.

Now let's skip ahead to the SetMosfet function. We will come back to the rest of the code afterwards.
void SetMosfet(int val)
{
  digitalWrite(13, val);
  digitalWrite(MOSFET_PIN, val);
}

The SetMosfet part is called a function. That means that we can call it from other parts of the code. When writing Eg. SetMosfet(HIGH); the arduino jumps to this part does what's written in the SetMosfet function and then contimues where it was.
Now the 2 lines of code say "digitalWrite" then it gives a pin number (13 and then MOSFET_PIN). That means that we will be setting the value of that pin eighther HIGH => 5v or LOW => 0v. But instead of writing HIGH or LOW we write "val" (short for value). This is because val was defigned as an input to the SetMosfet function in the first line "void SetMosfet(int val)" meaning the function takes a value as input and names that value "val". So in the rest of the code we can write SetMosfet(LOW); to turn off the mosfet, preventing the gun from shooting, or SetMosfet(HIGH); to turn it on letting the gun shoot. And with the same one line of code the LED on pin 13 will be set to the same value. So when the gun is shooting the LED is lighting up.
void ReadTrigger()
{
  int TriggerReadValue = analogRead(TRIGGER_PIN);
    
  TrigerStatus = LOW;
  if(TriggerReadValue > 20) {
      TrigerStatus = HIGH;
  }
}

We also have the above function in the code. The ReadTrigger function does not have any input so it's used just by writing "ReadTrigger();". What the function does is to analogRead the TRIGGER_PIN value. This means that it sees what the voltage level is at the trigger (through the voltage divider). So as described above the 7.4v lipo would give a value of 138. That value of 138 is saved in the "TriggerReadValue" memmory.

Then it get's a little more complicated. The "TrigerStatus" value is set to LOW meaning the trigger is not pulled (eaven though with a value of 138 it clearly is pulled) and then if the value is above 20 it changes the TrigerStatus to HIGH. In this way when we in other parts of the code call ReadTrigger(); we know that after this line the TrigerStatus has been updated with HIGH or LOW depending on what state the trigger is in.

So now that we have all this let's dive into the rest of the code. A section at a time:
// The loop routine runs over and over again forever.
void loop() {
  ReadTrigger();
  if(TrigerStatus == HIGH)
  {
    //......... More code here .......  
  }
}

The loop function is a function that the arduino runs over and over and over in an endless loop. And in this endless loop the first thing that happens is that it calls the ReadTrigger(); function (Remember the description from before?). So the TrigerStatus is updated. Then it say that if the TrigerStatus == HIGH meaning that the arduino checks if the TrigerStatus value is HIGH or LOW and if it is HIGH then it runs the code betwen the "{" and "}". So the arduino repedetly checks if the trigger is pulled and only if it is pulled it does something.
    SetMosfet(HIGH);
    while (TrigerStatus == HIGH) 
    {
      //......... More code here .......  
    }
    SetMosfet(LOW);
    CurrentSleepTime = 0;
}

As I just described the above segment of code is only run when the trigger is pulled. So when you pull the trigger the first thing that the arduino does is open the mosfet with the SetMosfet(HIGH); function. So now the motor starts turning and the gun will shoot. But we need to do more than just get it to shoot. so while the TrigerStatus is (==) HIGH we do som more work described below. And when the TrigerStatus changes to LOW meaning you release the trigger. We then SetMosfet(LOW); meaning we stop the mosfet => not power gets to the motor and the gun stop's shooting. Last but not least we reset the "CurrentSleepTime" value to 0, so that no mater what is was before, when the trigger is released it is set to 0.

      if(CurrentSleepTime < Max_ON_Time)
	  {
        CurrentSleepTime = CurrentSleepTime + 1;
      } else {
        SetMosfet(LOW);
      }
      delay(1);
      ReadTrigger();
}

Now the last peace of code will run while the trigger is helled in (or keept pressed). So in this state we check how long time the trigger has been pressed. if the trigger has been pressed "CurrentSleepTime" less than the ammount of time defigned in the beginning in the "Max_ON_Time" variable. The "CurrentSleepTime" is counted up with one, and the arduino will delay(1); meaning wait 1 millisecond. So in this way the CurrentSleepTime will be the ammount of time (in milliseconds) that the trigger has been pressed. Note that executing the code on the arduino does take som time, so it's not 100% precise so the "Max_ON_Time" will need to be set to a higher value than what was calculated in the beginning.

Now if the time that has passed (the CurrentSleepTime) excides the "Max_ON_Time" then the SetMosfet(LOW); function is called turning off the motor and stopping the gun from shooting. But because the above code ALWAYS keeps running while the trigger is pressed the motor neaver start again eaven if the trigger is still pressed in. So what we effectivly did was to stop the gun shooting (after the first 3 shots) eaven thoug the user is still pressing the trigger. Now that's how 3 burst mode works :-) The last thing we need to doo is to remember to keep checking is the trigger is released ReadTrigger(); so that when you release the trigger everything reset's and wait for the next time you press the trigger.


That's it, now you know how the code work.


Upload the code to the Arduino:
There are MANY arduino guides on the net. Try to
Google arduino code upload and see what comes up. Or if you are into video guides just Youtube search instead.. This will cover any details that I may miss. But if you are just into a short step by step guide for this particular project here it is:

First install the Arduino IDE (Integrated Development Environment). Download from here: Download Link it's free so no money needed.
Then start up the IDE. You should see something in the line of the below right side window.



Now you should download (or just open in a browser) the code you want to try out. I recomend starting with the simple version! When you get that working you know how to doo things and what basic values you need. Then you can always get the more advanced versions later.
Copy ALL the code in the downloaded text file into the arduino IDE.
Go to the "tools" menu and under "boards" select the "Arduino Nano" option.



Go to the "File" menu and select "Save As..." to save the arduino file. Now remember you MUST name the folder you save it in the same as the file name you select. Eg. Folder: Someting\MoreFolder\ASCU and file name ASCU.ino. [I called it SimpleVersion in the image.]
Now with the sketch (Arduino calles it a sketch) saved, and nano board selected, you can press the verify to make sure everything is ready.
If it all succeds you should see the "Done compiling" text and some white text sayng "sketch uses ... bytes ( some number %)" if instead it fails and red text appear there has been an error. (GOOGLE THE ERROR AND FIND HELP)



Now plug in the Arduino using the USB cable. First plug the cable into the Arduino.
Then the cable into a USB port of the computer.
Now just wait a moment for the arduino to prepare, and for the drivers to be installed correctly.
Then in the arduino "Tools" menu you should be able to find a "COM port" with a number that was not there before you plugged it in. Select that new Com port.
And last but not least press the "Upload button". This will upload the code to the arduino.



That's it. When it's done uploading it should work.


Download the code:
Here I will be posting code updates and new versions when I make changes. I will try to keep the old versions here also. But if it get's crouded I may move older versions some where else.

First off I reccoment that people start by getting a simple version to work. So I will start by giving you the simplelest version. If you want more advanced versions then just scroll down and find a version with the fetaures you want.

- The most simple version there is.
Simple Version 1.0 - Download

- Simple version. With Full auto switch. Harware modifications required
Simple Version 2.0 - Download (Full auto switch)

- Advanced version. With low voltage battery cut-off protection. (No full auto switch)
Advanced Version 1.0 - Download (Battery protection)

- With Full auto switch. Harware modifications required
- Added support for PWM Motor speed control. (To control Rate Of Fire)
Advanced Version 2.0 - Download (Battery protection, Full auto switch, PWM Motor Speed control)

In the future I may make a page deficated to the advanced versions. If anyone want's me to ??? Please write me (use the support contact link) if you want me to make a show about the advanced version.