Build guide: Rotary inverted pendulum kit (Furuta pendulum)
Code for this guide
A stepper motor swings a horizontal arm; a free pendulum hangs from the arm's end. The firmware swings the pendulum up and balances it upright. Build time: 3–4 hours. Level: intermediate.
1. What's in the box
| Part | Qty | Used for |
|---|---|---|
| Arduino Nano (CH340) | 1 | Controller |
| NEMA 17 stepper motor, 40 mm | 1 | Turns the arm |
| TMC2209 stepper driver | 1 | Drives the motor quietly and smoothly |
| AS5600 magnetic encoder with magnet | 1 | Measures the pendulum angle |
| 608 ball bearings | 2 | Pendulum pivot |
| 12 V 5 A power supply | 1 | Power |
| M3 screw and nut kit | 1 | Assembly |
| Printed parts: base with motor tower, arm, pendulum, magnet cap | 4 | Structure |
| Wiring harness, power lead with DC jack, encoder cable | 1 set | Wiring |
| M8 × 50 bolt, 2 washers, 2 nuts; M3 grub screw | 1 set | Pivot shaft, arm hub |
You also need: a computer, a USB Mini-B cable, the Arduino IDE (free), and a 2.5 mm hex key and a small screwdriver. Python 3 with numpy is optional (for designing your own controller).
2. Assembly
- Motor into the tower. Feed the motor cable down through the tower and out of the side window. Push the motor's round boss up into the hole in the tower's top plate, shaft up, and fix it with four M3 × 8 screws from above.
- Bearings into the arm. Press one 608 bearing into each end of the arm's round housing until it stops against the lip in the middle. Use a vice or press on the outer ring only.
- Pivot bolt. From the encoder-bracket side, pass the M8 bolt through the bracket opening and both bearings. On the far side, add a washer and one nut and tighten until the bolt turns freely with no play (not tight: the inner rings must still spin).
- Magnet. Press the magnet cap over the bolt head and glue the round magnet into its pocket with a drop of superglue, centred. The magnet must be the diametric one from the encoder bag.
- Encoder. Screw the AS5600 board to the bracket, chip facing the magnet, with M3 screws and nuts. Slide it in the slots until the chip is centred on the bolt. Gap between chip and magnet: 1–3 mm (use washers as spacers). Wire the board's DIR pin to GND (the harness does this).
- Pendulum. Slide the pendulum's hub onto the bolt after the nut, so it hangs straight down, and tighten the pinch screw. Lock with the second nut.
- Arm onto the motor. Push the arm hub onto the motor shaft, flat side towards the grub screw, about 2 mm above the tower. Tighten the M3 grub screw onto the flat.
- Check: the pendulum swings freely for 20+ seconds after a push. If it stops quickly, loosen the pivot nut slightly.
3. Wiring
The harness is pre-wired. Connect it as follows (Nano pin → device):
| Nano | Connects to |
|---|---|
| D2 | TMC2209 STEP |
| D3 | TMC2209 DIR |
| D4 | TMC2209 EN |
| 5V, GND | TMC2209 VIO and GND; AS5600 VCC and GND |
| A4 | AS5600 SDA |
| A5 | AS5600 SCL |
- TMC2209 MS1 and MS2 → GND (1/8 microstepping). VM → 12 V, GND → supply GND (the 100 µF capacitor across VM/GND is on the harness: never run the driver without it).
- Motor coils to the driver's A1/A2 and B1/B2 (the harness plug only fits one way).
- The Nano is powered from USB while you program it; the motor needs the 12 V supply plugged in.
- Never unplug the motor while the 12 V supply is on: it can destroy the driver.
4. Firmware
- Install the Arduino IDE. Download the firmware (
pendulum.ino, linked at the top of this guide) into a folder namedpendulumand open it. - Tools → Board: Arduino Nano; Processor: ATmega328P (Old Bootloader) for most CH340 boards.
- Upload. Open the Serial Monitor at 115200 baud, line ending Newline.
5. First run
- Plug in the 12 V supply. Let the pendulum hang still. Hold the base down with one hand.
- Type
sand press Enter. The arm makes a small jog (this finds the encoder direction), waits, then swings the pendulum up and balances it, usually within 2–5 seconds. - Type
xto stop at any time. The firmware also stops by itself if the arm turns more than 2.5 rad (about 140°) either way, to protect the encoder cable.
If it doesn't balance, see Troubleshooting. Most rigs balance with the default gains.
6. Logging and tuning
lstreamsms,theta,phi,dtheta,dphi,u,modeat 100 Hz (copy from the Serial Monitor into a CSV).pprints the current gains and angles.g k1 k2 k3 k4sets the balance (LQR) gains;e ke kc kd smsets the swing-up gains.
Design your own controller. python/furuta.py holds the model of this rig. Weigh your pendulum and
put its mass in Rig, measure the friction from a free swing (time how long the swing takes to halve,
then fit b), and run:
python3 furuta.py
It prints LQR gains for your rig as a g … line to paste into the console, and simulates a swing-up and
balance (it saves a plot if matplotlib is installed). Try different weights Q and R and see how the
real pendulum's behaviour changes.
7. Experiments
- System identification: fit the pendulum's natural frequency and damping from a free swing.
- Pole placement vs LQR: design both from the same model and compare disturbance rejection.
- Swing-up: change
keandsmand see how fast and how violently it swings up. - Robustness: add a small weight (a nut) at the tip and see which controller still balances.
- Sim-to-real: compare logged data with the simulation from the same starting point.
8. Troubleshooting
| Symptom | Fix |
|---|---|
| "Encoder didn't see the pendulum move" | Magnet glued off-centre or the gap is over 3 mm; check SDA/SCL and 5 V |
| Motor buzzes but doesn't turn | Swap one coil pair; check the 12 V supply is on |
| Swings up but overshoots and falls | Reduce ke (try e 0.6 80 5 60) |
| Balances but the arm drifts to the limit | Make k1 and k3 more negative (stronger arm centring) |
| Jitters while balancing | Increase the encoder gap slightly, or reduce k4 |
| Arm slips on the shaft | Tighten the grub screw onto the flat of the shaft |
9. Safety
The arm moves fast. Keep fingers, hair and cables clear while it runs, and stop with x before touching
it. Use only the supplied 12 V supply.
© 2026 Voltomni. The firmware and Python model are free to use, change and share for learning and teaching. Questions: [email protected].