Introduction: 3D Printed Servo Motor

About: Mechanical engineering student at Purdue University. 3D printing, robots, and various mechanisms.

Most hobby servos are limited to less than 360° of rotation. Let's fix that! In this build, I'll show you how to make a 3D-printed servo motor. Like traditional servos, this servo has position feedback. Unlike a traditional servo, this servo has 3D printed gears, is much faster and stronger, and has 360° of rotation. This is quite a simple build. I finished this project from start to finish in a weekend. Let's begin.

Supplies

Tools

  • needle nose pliers
  • wire cutters
  • wire strippers
  • 2.5mm allen wrench
  • soldering iron and solder
  • exacto knife
  • hot glue gun and hot glue
  • hammer

Parts ($58.86)


Electronics ($41.97)

Other supplies ($16.89)

Step 1: 3D Print the Parts

First, let's print the parts. I designed this servo in Autodesk Inventor. The design is quite simple. It is essentially a gearbox with a 3:1 gear ratio that is mounted onto a DC motor. There are 6 3D-printed parts in total:

  • gearbox
  • gearbox case
  • 18 tooth gear
  • 54 tooth gear
  • output shaft
  • servo arm

I printed all of these parts in PLA filament. I have attached all of the STL files below.

I'd recommend using the following printer settings:

  • 20% infill
  • Auto-generated supports
  • PLA (210° extruder and 45° bed)

The total filament usage is about 50g. It took a cumulative 4 hours to print all 6 parts.

360_Servo

Step 2: Add the Threaded Inserts

Now let's add threaded inserts into some of the 3D-printed parts. These inserts serve as threads for the screws to screw into. You will need 12 inserts in total. The parts requiring these inserts are as follows:

  • gearbox (4 inserts)
  • gearbox cover (4 inserts)
  • 54 tooth gear (4 inserts)

Use a heated soldering iron to press these inserts into the parts.

Step 3: Encoder Setup

While regular servos use potentiometers to get position feedback, this servo uses an encoder. The AS5600 absolute encoder will read the position of the servo and send it to the Arduino. You will want to wire a servo cable to the 3 leads on the encoder so that it can be connected to the Arduino. Next, press the encoder into the gearbox and hold the wires down with some hot glue. Now press the encoder magnet into the 54-tooth gear. This allows the encoder to read the gear's position as the gear rotates.




Step 4: Create the Gearbox Cover

To make the gearbox cover

  • Push the bearing into to the gearbox case (you will need a hammer for this).
  • Push the 54-tooth gear into the bearing.
  • Screw the output shaft onto the 54 tooth gear using m3 x 10mm screws (x 2).

Step 5: Add the DC Motor

Now let's screw the DC motor onto the main gearbox using m3 x 5mm screws (x 3). Then push the 18-tooth gear into the DC motor (you will need a hammer for this). Due to the fact that the DC motor's shaft is a D shaft and because the 18-tooth gear is a tight fit, the gear should not slip.

Step 6: Create the Gearbox

Now let's finish making the servo:

  • Use m3 x 10mm screws (x 4) to screw the gearbox cover onto the gearbox
  • Use m3 x 15mm screws (x 2) to screw the servo arm onto the output shaft

Step 7: BTS7960

The BTS7960 motor driver is what we will use to drive the motor. One slight modification must be made to the driver. The driver has 2 pins labeled (44)PWM on the diagram in Image #3. These pins need to be soldered together as shown in Image #2. This creates the enable pin.Individually these pins are the enable pins for the LPWM pin and the RPWM pin. Since these pins must always be in the same state (if one is set to HIGH the other must also be set to HIGH), soldering them saves one pin on the Arduino.

I recommend soldering a servo cable to the RPWM, and LPWM, and enable pin (the pins we just soldered together) as shown in Image #1. This will make connecting the driver to the Arduino easier.

Step 8: Electronics

Creating the Circuit is as simple as following the schematic shown in Image #6 (also available in PDF form below). The following is a description of the schematic.

AS5600

  • GND - connects to Arduino GND pin
  • 5V - connects Arduino 5V pin
  • PWM - connects to the Arduino analog pin A0

DC motor

  • Both leads on the motor connect to the BTS7960 motor driver M+ and M- pins. It doesn't matter which connects to which.
  • Note: The motor is rated for 24V. It doesn't have to be exactly 24V. I used about 22 as shown in Image #4.

Power supply

  • GND - connects to B- on the BTS7960
  • VCC - connects to B+ on the BTS7960

BTS7960

  • Enable pin (aka the pins we soldered) - connects to Arduino pin 2
  • LPWM - connects to Arduino pin 5
  • RPWM - connects to Arduino pin 6
  • **Note** As you will see in the next step, the L_PWM and RPWM pins' placement on Arduino pins 5 and 6 is completely arbitrary. We will have to confirm that this is the right placement when we upload the Arduino sketch. In other words, it doesn't matter if you connect the L_PWM and R_PWM pins to Arduino pins 5 and 6 respectively, or Arduino pins 6 and 5 respectively.

**Note** All GND pins on all components are connected together.

Step 9: Upload the Sketch

Now let's upload the sketch. Download the Arduino sketch below and uncomment the first line in the void loop section. Change the value in parentheses to the position that you wish to move the servo to (it should look like Image #2). Now upload the sketch. If everything works, the servo should move to that position.

If you find that the servo never settles at a point and moves back and forth really fast then you have the DC motor hooked up wrong. You can fix this in one of two ways:

  1. Switch which motor lead is hooked onto M+ and M- on the BTS7960.
  2. Change the PWM pin assignment on line #2 of the program from {5, 6} to {6, 5} shown Image #1.

How This Works

The Arduino controls the position of the servo using a method known as closed-loop control. This is similar to how a normal servo works. The Arduino continuously moves the servo to a setpoint. When you type a value into the function moveTo() you are setting this setpoint.

Offset Values

You will notice that the position of the servo is quite arbitrary since we simply put the encoder magnet into the gear randomly. To change this, change the variable called offset (shown in Image #1). For example: If I want the current 0° position to be where the current 60° position is, make the offset value 60. Likewise, if I wanted the 0° position to be where the 320° position is, make the offset -40.

Reading The Servo's Position

Unlike potentiometers used in traditional servos, the AS5600 encoder allows us to read the position of the servo. To have this position displayed, uncomment the 2nd line in the void loop section. This line reads Serial.println(getPos()). The getPos() function returns the position of the servo that's read from the absolute encoder. This section of the code is shown in Image #3.

Typing Position Values To The Serial Monitor

If you would like to type different positions for the servo to turn to, uncomment the 2nd line in the void loop section. This is a function called inputPos(). When you upload this sketch you can type different positions for the servo to turn to. This section of the code is shown in Image #4.

Step 10: Using the Servo for Other Projects

If you'd like to customize this servo for different projects I'd recommend looking into the following:

Changing Speed/Torque

  • The speed and torque of the servo can only be changed by changing the DC motor. You can purchase DC motors with different speed and torque ratings at the same link to purchase the 600 rpm DC motor. A slower DC motor will give you more torque since it has a higher gear reduction.

Changing Pins On The Arduino

  • Changing the pin assignment of the RPWM and LPWM pins on the Arduino is pretty simple. As long as you change the pin assignment in the program as well as on the Arduino the program should work just fine. The only thing to remember is that the RPWM and LPWM pins must connect to a PWM pin on the Arduino. You can also change the pin assignment of the encoder. Similarly, the encoder can only connect to analog pins on the Arduino.

Mounting The Servo

  • Part of the design of the gearbox is a spot for 4 threaded insets on top of the gearbox which were not utilized in this build. This is done so that the gearbox can be mounted onto other parts. The distances between these inserts are labeled in Image #3.

Creating Servo Arms

  • The servo arm used in this project is just a test arm. If you want to use a different servo arm you will have to CAD your own. The only requirement is that you add two holes spaced 0.75" apart so that the arm can be mounted onto the output shaft. This is labeled in Image #4.

Programming The Servo To Actuate

  • The program given in the previous step moves the servo to a single position. If you wish to sweep the servo check out the program below (also shown in Image #5). It sweeps the servo from 0 to 90 degrees every 500 milliseconds.