Step 1: Let's Spin a Stepper Motor with Raspberry Pi!
Hello everyone! This is Eric Park, 3D Printer Engineer from South Korea.
Welcome to the first real step of our journey — "Making a Controller with Raspberry Pi"!
If you haven't read my introduction post yet, here's the short version: I'm a 3D printer engineer who couldn't understand Marlin or Klipper code, so I decided to study from the very basics — with the help of AI (Claude). And now I want to share everything I learn, step by step, with anyone who feels the same way I did.
Today is Step 1: Make the motor spin. That's it. Simple. Fun. Let's go!
What You Need (BOM - Bill of Materials)
Messy Desk ;)
Wiring Diagram
Note: I'll add a proper image diagram soon! For now, here's the connection table and an ASCII diagram to get you started.
Raspberry Pi GPIO A4988 Driver Board
─────────────────────────────────────────────
GPIO 4 (Pin 7) ──────► STEP
GPIO 3 (Pin 5) ──────► DIR
GPIO 2 (Pin 3) ──────► ENABLE (active LOW)
GND ──────► GND (logic side)
12V Power Supply
─────────────────────────────────────────────
12V (+) ──────► VMOT
GND (-) ──────► GND (motor side)
Stepper Motor ──────► A, A̅, B, B̅ (4 wires)
Important notes:
- The A4988 has two GND pins — one for logic (connect to RPi GND), one for motor power (connect to 12V GND)
- Set the current limit on your A4988 before connecting the motor! (Turn the potentiometer carefully)
- ENABLE pin is active LOW — meaning
LOW= motor ON,HIGH= motor OFF
The Code — Step 1
Let's look at the code together. I'll explain each part so we can understand what's happening!
/*
* step1.c
* Basic Stepper Motor Control
*
* Goal:
* - Understand GPIO control
* - Generate step pulses to spin the motor
* - Control direction
*/
#include <wiringPi.h> // Raspberry Pi GPIO library
#include <stdio.h>
// === Pin Definitions ===
// We use BCM GPIO numbers (wiringPiSetupGpio mode)
#define STEP_PIN 4 // GPIO 4 → sends pulses to move motor
#define DIR_PIN 3 // GPIO 3 → sets rotation direction
#define ENABLE_PIN 2 // GPIO 2 → enables/disables motor
// === Settings ===
#define STEPS_TO_MOVE 200 // 200 steps = 1 full revolution (for 1.8° motor)
#define STEP_DELAY_US 1000 // delay between pulses in microseconds (= speed)
int main(void) {
// Step 1: Initialize wiringPi with BCM GPIO numbering
if (wiringPiSetupGpio() == -1) {
printf("wiringPi init failed!\n");
return 1;
}
// Step 2: Set pin modes
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(ENABLE_PIN, OUTPUT);
// Step 3: Enable the motor driver (ENABLE is active LOW)
digitalWrite(ENABLE_PIN, LOW);
printf("Motor enabled!\n");
delay(500); // small wait after enable
// Step 4: Set direction (HIGH = one way, LOW = other way)
digitalWrite(DIR_PIN, HIGH);
printf("Direction: Forward\n");
// Step 5: Send step pulses!
printf("Moving %d steps...\n", STEPS_TO_MOVE);
for (int i = 0; i < STEPS_TO_MOVE; i++) {
// One pulse = one step
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(STEP_DELAY_US); // pulse ON time
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(STEP_DELAY_US); // pulse OFF time
}
printf("Done! Motor moved %d steps.\n", STEPS_TO_MOVE);
// Step 6: Disable motor (saves power, reduces heat)
digitalWrite(ENABLE_PIN, HIGH);
printf("Motor disabled.\n");
return 0;
}
Code Explanation — Let's Read It Together
1. #include <wiringPi.h>
This is the library that lets us control the Raspberry Pi's GPIO pins from C code. Think of it as the "translator" between our code and the hardware pins.
2. Pin Definitions (#define)
#define STEP_PIN 4
#define DIR_PIN 3
#define ENABLE_PIN 2
Instead of writing the number 4 everywhere in the code, we give it a name STEP_PIN. This makes the code much easier to read and change later. This is a very common practice in C!
3. wiringPiSetupGpio()
This tells wiringPi: "I want to use standard BCM GPIO numbers." It must be called once at the very start, before using any GPIO functions.
4. pinMode(pin, OUTPUT)
Each GPIO pin can work as either INPUT (read a signal) or OUTPUT (send a signal). Since we're sending pulses to the motor driver, we set all three pins as OUTPUT.
5. The ENABLE Pin — Active LOW Logic
digitalWrite(ENABLE_PIN, LOW); // LOW = ON (motor enabled)
This is a little confusing at first! The A4988 driver uses "active LOW" logic for ENABLE, which means:
-
LOW (0V)→ Motor is ENABLED -
HIGH (3.3V)→ Motor is DISABLED
This is common in electronics — don't worry, you'll get used to it!
6. The Step Pulse Loop
for (int i = 0; i < STEPS_TO_MOVE; i++) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(STEP_DELAY_US);
digitalWrite(STEP_PIN, LOW);
delayMicroseconds(STEP_DELAY_US);
}
Each loop iteration = one step of the motor.
One step is created by:
- Pulling STEP pin
HIGH→ motor driver detects rising edge → motor moves one step - Waiting (
delayMicroseconds) → this controls speed! - Pulling STEP pin
LOW→ ready for the next pulse
Key insight: The smaller the delay, the faster the motor spins!
Try changing STEP_DELAY_US from 1000 to 500 and see what happens.
How to Compile and Run
# Compile
gcc step1.c -o step1 -lwiringPi
# Run (needs sudo for GPIO access)
sudo ./step1
Expected output:
Motor enabled!
Direction: Forward
Moving 200 steps...
Done! Motor moved 200 steps.
Motor disabled.
What Did We Learn?
- How to set up GPIO pins with wiringPi
- What STEP, DIR, and ENABLE pins do
- How a step pulse works (HIGH → delay → LOW → delay)
- How delay time controls motor speed
- Active LOW logic (ENABLE pin)
What's Next? (Step 2 Preview)
Right now, our motor just spins 200 steps and stops. But what if we want to control how many mm it moves, or make it go back and forth?
Next week (Step 2), we'll add:
- Direction control — forward and backward
- Loop for continuous movement
- Start thinking about converting steps to mm
See you next Thursday!
Let's Talk!
Have any questions? Did your motor spin? Did it NOT spin? Let me know in the comments!
If you're in a similar situation — an engineer who wants to understand the code behind their machines — I hope this series helps you feel less alone in that journey. We're learning together.
And if you have questions about 3D printing, Korea, or anything else — feel free to reach out anytime!
Eric Park, from Daegu, South Korea
Tags: raspberrypi C steppermotor 3dprinting beginners embedded

Top comments (0)