October 12, 2025
Description
Introducing my Automatic Magazine Loader for .223/5.56 calibers!
Â
Powered by a Ryobi 18v tool battery you can now make your own automatic magazine loader for .223/5.56 caliber magazines!
Please read full description below. Â This design has been updated from my previous design and now includes a 2nd hopper servo for strength, the code for the Arduino build does not reflect this change and must be updated. Â The code for the Pololu does.
Â
The Machine can still operate on one hopper servo.
Â
A drop in copy paste Arduino code is provided to get you loading quickly!
Plug n Play codes are in the description below, one for the Pololu Micro Controller and one for Arduino (ESP32) Controllers
Â
Function video below
Â
Â
Function video available here; Loader in video was a prototype, Loader you will build functions the same, video updates to come
Fully Loaded hopper with 60 rounds. Â
Â
This Loader uses commonly available electronics and hardware all available on amazon.
Â
How it Works! (Arduino)
When the power button is pressed the program starts an 11 cycle run. Â The first of which is a "priming" run. Â When the cycle starts the chamber is empty, the pusher block moves forward at the same time the hopper agitator moves up and grabs a round. Â During the 2nd part of the cycle the pusher block retracts opening the chamber as the agitator brings the round down into the throat where it falls tip down into the mag well. Â This cycle repeats but now that the machine is "primed" it begins loading the magazine and will continue until the 11th cycle where it will stop or you power it off.
Â
How it Works! (Pololu Micro Controller)
When the power button is pressed the Hopper servos retract the gear racks and allow the Agitator to fall bringing a round into the Hopper Throat where it will automatically orient itself tip down. Â Then the Charging Servo moves the Charging Block forward pushing the round into the magazine. Â This cycle loops 10 times (more or less depending on the code, mine is set for 10). Â Once the cycle is complete the servos move into a "Hold" position with the Charging Block in the retracted position and the Agitator in the Up Loading position. Â Pressing the Power button off and on again will repeat this process. Â Pressing the optional Momentary button will run the cycle 1 time to load a single round then return to the hold position.
Depending on the type of controller you chose your code may be different, the Pololu controller uses its own GUI. Â Programming is done by using sliders to visually see the servo positions. Â No coding necessary, unlike doing this via Arduino. Its more expensive but i like it better.
Â
Materials Needed
PLA
1x 25kg or better metal gear standard servoÂ
2x MG90 Servos
1x LM2596 DC Buck converter
2x keystone battery contacts
1x servo controller (Pololu micro maestro 6, Arduino, ESP32)
2x springs both about 20mm long, 1x 5mm dia, the other 7mm or close
1x 12mm Latching Push button switch
21x m3 screws (whatever length works mainly 20mm and 12mm)
1x m4x30mm screw
Super Glue
4x servo mounting screws (usually included with 9g servos)
miscellaneous lengths of 18awg wire
Â
My project uses the Pololu Micro Maestro 6, a 6-channel servo controller. Â I initially built it with an Arduino nano 33 but the Pololu having a simple free gui is extremely simply. No coding. Â AI wrote the code I used with the nano 33 and ESP 32 and it worked fine. Â Drop in copy pastes codes are below.
Â
Wiring description: Â set buck converter voltage according to servo requirements
Â
Battery Positive to leg 1 of switch
Leg 2 of switch to positive input of buck converter
Battery negative to negative input of buck converter
Output Positive and Negative of buck converter to power inputs on controller
Connect servos to channels chosen during gui programming...done
This project was inspired by a manual loader i found years ago and completely redesigned so thanks to AWCY AR15 Magazine loader. Â https://odysee.com/@AreWeCoolYet:7/ARMagloader:6
Also, thanks to the designer of the Ryobi receiver, which was heavily modified. Â https://www.thingiverse.com/thing:5412740
The included files may look slightly different than my images because I made some slight changes to make it easier to assemble and disassemble. Â The printable machine is designed to be able to remove the top covers independently if you need to service something.
The holes in Rear Cover are for the main power switch and an optional manual cycle momentary switch as well as 2x 5mm leds. Â I added a power led and a "Status" led that blinks with the cycle, as programmed into my controller.
Feet, if you load 30rd mags you'll need to add some feet to the bottom about 1/4" tall so the bend in the mag clears the table the machine sits on. Â 10rd and 20rd mags are fine even the 20rd curved body mags will work like the "Hexmag shorty".
Â
Hopper
The Hopper is designed to be removable for transport, but you must remove or leave out the 2 lower m3 screws holding it to the front cover. Â The Hopper top and Hopper Throat at held together by the thicker Bullet shaped tabs that are simple super glued to the 2 parts. Â The hopper servo mount has a track that keeps the gear rack in line and allows for easy alignment. Â Simply attach the servo mount to the interface with super glue and drop the gear rack into the slot with the tab at the top. Â With the gear rack in about the middle place the servo with the pinion gear back into place. Â The gear rack tab should rest 1 tooth slightly higher than the top of the servo bracket.
The Agitator slides into the hopper from the top and rests on top of the gear rack tab. Â Secure the Agitator inside the hopper with 2 m3 screws accessible from the holes in the bottom front of the hopper throat, make sure these screws don't protrude beyond the thickness of the agitator.
Â
Once you install the hopper, I recommend testing it with a single round without the magazine just in case you didn't get it just right. Â The hopper agitator needs to move the full servo travel, if the rounds don't fall into the throat, you may be 1 tooth off on the rack gear.
In my Prototype I used both a Nano 33 and in the final code which I will attach below, an ESP32. Â I chose the ESP32 due to is high availability and low cost. Â
The code below will work on both types of boards with the exception of the first line of code indicating the servo library.
If you go with Arduino boards, you'll need to use this code in the first line; #include <Servo.h>
If you go with ESP32 boards, you'll need to use this code in the first line; #include <ESP32Servo.h>
The code reflects the pins I chose to use, so if you chose different pins for your servo signal wires, you'll need to change the pin number in the code. Â
The Pusher servo (25kg) is meant to move from 90 to 150 and back to 90, and the Hopper servos from 0 to 180 to 0 again. Â
You will need to align the horn and rack gear accordingly to allow for this. Â
Â
I recommend using a servo tester to first move the 9g servos to the full positions when it is in its designed orientation. Â This will allow it to start in the Hopper loading position aka rack gear up so that when the sequence starts the first move is to pull a round from the hopper into the throat and chamber setting it up to be loaded in the next step.
Â
The Pusher servo (25kg) should be positioned in the middle neutral position and the horn placed on the splines and linkage so that the Pusher block is in the retracted position, the chamber should be clear. Â This will allow the incoming round to fall free into the chamber to be pushed in. Â Make sure it isn't so far back that when it retracts it hits the servo. Â It should stop about 1mm away.
Â
Copy and paste the following Arduino code into the IDE and change Pin numbers and servo library if you build yours differently. Â This will get your machine Loading! Â Feel free to improve and share your results! Â
NOTE The Arduino code does not account for the 2nd servo i designed it for so youll need to modify the code to add it. Â The code for the Pololu does. Â The Machine originally operated with a single hopper servo but i find its would be better with a bit more strength. Â You can still run it on 1 servo.
Â
OR
Â
Copy and paste the code for the pololu controller into its gui and apply settings provided you connected your peripherals the same way i did. Â code at bottom.
Happy Loading
Â
#include <ESP32Servo.h>
// Create servo objects
Servo servo1;
Servo servo2;
// Define the pins
const int servo1Pin = 5;
const int servo2Pin = 17;
const int buttonPin = 19;
// Track button state
int buttonState;
int lastButtonState = LOW;
long lastDebounceTime = 0;
long debounceDelay = 50;
bool buttonIsPressed = false;
// Variables for control flow
int loopCount = 0;
const int totalLoops = 10;
bool hasStarted = false;
void setup() {
Serial.begin(9600);
// Attach servos to pins
servo1.attach(servo1Pin);
servo2.attach(servo2Pin);
// Set the initial position of the servos
servo1.write(90);
servo2.write(0);
// Configure button pin with internal pull-up resistor
// This simplifies wiring by eliminating the need for an external resistor.
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
// Read the state of the button
int reading = digitalRead(buttonPin);
// Debounce the button press
if (reading != lastButtonState) {
 lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
 if (reading != buttonState) {
  buttonState = reading;
  // The button is pressed when the reading goes LOW (due to INPUT_PULLUP)
  if (buttonState == LOW) {
   buttonIsPressed = true;
  }
 }
}
// If the button was pressed and the sequence is not already running
if (buttonIsPressed && !hasStarted) {
 Serial.println("Button pressed. Starting servo sequence.");
 hasStarted = true;
 buttonIsPressed = false;
 loopCount = 0;
}
// Run the sequence 10 times
if (hasStarted && loopCount < totalLoops) {
 // Move servo 1 from 90 to 150 and back to 90
 // Move servo 2 from 0 to 180 and back to 0
 servo2.write(180);
 delay(1000);
 servo2.write(0);
 delay(1000);
 // Move servo 1 from 90 to 150 and back to 90
 servo1.write(150);
 delay(1000);
 servo1.write(90);
 delay(1000);
Â
 // Increment the counter
 loopCount++;
 Serial.print("Completed loop ");
 Serial.println(loopCount);
 // Reset the sequence after the last loop
 if (loopCount >= totalLoops) {
  Serial.println("Sequence finished.");
  hasStarted = false;
 }
}
lastButtonState = reading;
}
Â
Pololu Script
Sequence_0
begin
 #if the button reads low:
 3 get_position 500 less_than if
  #run the following code:
 1000 2048 0 6000 2624 8000 frame_0..2_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 frame_0 # Retract Hold Â
endif
 #short delay to control loop speed
 10 delay
repeat
#the rest of your code can go under this as-is:
### Sequence subroutines: ###
# Sequence 0
sub Sequence_0
 1000 2048 0 8000 2624 8000 frame_0..2_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 0 2624 8000 frame_0_1_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 0 2624 8000 frame_0_1_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 0 2624 8000 frame_0_1_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 0 2624 8000 frame_0_1_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 0 2624 8000 frame_0_1_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 0 2624 8000 frame_0_1_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 0 2624 8000 frame_0_1_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 0 2624 8000 frame_0_1_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 0 2624 8000 frame_0_1_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 0 frame_0_4 # Retract Hold
 return
# Sequence 1
sub Sequence_1
 1000 2048 0 6000 2624 8000 frame_0..2_4_5 # Retract
 700 4128 8000 8000 2624 frame_0_1_4_5 # Load
 1000 2048 frame_0 # Retract Hold
 return
sub frame_0..2_4_5
 5 servo
 4 servo
 2 servo
 1 servo
 0 servo
 delay
 return
sub frame_0_1_4_5
 5 servo
 4 servo
 1 servo
 0 servo
 delay
 return
sub frame_0_4
 4 servo
 0 servo
 delay
 return
sub frame_0
 0 servo
 delay
 return
Â
Â
Amazon Purchase links for similar items I used
25kg servo, ASIN B07GJ6ZCVY
9g servo, ASIN B09KXM5L7Z
m3 socket head screw assortment, ASIN B0CSX4NX7R
LM2596 Buck Converter, ASIN B0FDB25T5L
Pololu Micro Maestro, ASIN B004G54CHW (cheaper through Pololu directly)
12mm Latching switch, ASIN B07YDCJFZJ
Spring Assortment, ASIN B0BVTDP29W
Keystone contacts, ASIN B06VTPWM6M
License:
Standard Digital File License
3,362