Arduino-Controlled Stepper Motor with Rotary Encoder and Potentiometer Speed Adjustment
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary
This circuit is designed to control a bipolar stepper motor using an Arduino UNO R4 WiFi microcontroller. The control is achieved through a stepper motor driver, which receives signals from the Arduino to drive the motor. The user can interact with the system using a rotary encoder and a potentiometer. The rotary encoder is used to set the position and direction of the stepper motor, while the potentiometer adjusts the speed. Additionally, the rotary encoder button enables fine movement control. The circuit is powered by a DC power source, and a rocker switch is used to turn the motor driver on and off.
Component List
Stepper Motor (Bipolar)
- Description: A bipolar stepper motor that can be driven by the stepper motor driver.
- Pins: D, B, C, A
STEPPER DRIVER
- Description: A driver module that controls the stepper motor based on signals from the Arduino.
- Pins: ENA -, ENA +, DIR -, DIR+, PUL -, PUL +, B-, B+, A-, A+, GND, VCC
Arduino UNO R4 WiFi
- Description: A microcontroller board based on the ATmega328, with integrated WiFi capability.
- Pins: OFF, GND, VRTC, IIC0_SCL, IIC0_SDA, 3V3, GPIO 41, GPIO 0, GPIO 42, GPIO 43, GPIO 44, BOOT, IOREF, RESET, 5V, VIN, A0, A1, A2, A3, A4, A5, RSPCKA, CIPO, COPI, D0/RX, D1/TX, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, AREF, SDA, SCL
Rotary Encoder
- Description: An input device that provides rotational position feedback and a push-button interface.
- Pins: clk, dt, sw, gnd, +
Potentiometer
- Description: A variable resistor that provides an adjustable voltage output.
- Pins: GND, Output, VCC
DC Power Source
- Description: Provides the electrical power for the circuit.
- Pins: Ground, Positive
Rocker Switch
- Description: A switch to control the power flow to the stepper motor driver.
- Pins: 1, 2
Wiring Details
Stepper Motor (Bipolar)
- D connected to STEPPER DRIVER B-
- B connected to STEPPER DRIVER B+
- C connected to STEPPER DRIVER A-
- A connected to STEPPER DRIVER A+
STEPPER DRIVER
- ENA - connected to Arduino UNO R4 WiFi D4
- ENA + connected to Rocker Switch 2, VCC, DIR+, PUL +, and Arduino UNO R4 WiFi VIN
- DIR - connected to Arduino UNO R4 WiFi D3
- PUL - connected to Arduino UNO R4 WiFi D2
- GND connected to DC Power Source Ground and Arduino UNO R4 WiFi GND
Arduino UNO R4 WiFi
- VIN connected to STEPPER DRIVER VCC
- GND connected to STEPPER DRIVER GND and DC Power Source Ground
- D2 connected to STEPPER DRIVER PUL -
- D3 connected to STEPPER DRIVER DIR -
- D4 connected to STEPPER DRIVER ENA -
- D5 connected to Rotary Encoder dt
- D6 connected to Rotary Encoder sw
- D7 connected to Rotary Encoder clk
- A0 connected to Potentiometer Output
- 5V connected to Potentiometer VCC and Rotary Encoder +
Rotary Encoder
- clk connected to Arduino UNO R4 WiFi D7
- dt connected to Arduino UNO R4 WiFi D5
- sw connected to Arduino UNO R4 WiFi D6
- gnd connected to Arduino UNO R4 WiFi GND
-
- connected to Arduino UNO R4 WiFi 5V
Potentiometer
- VCC connected to Arduino UNO R4 WiFi 5V
- Output connected to Arduino UNO R4 WiFi A0
- GND connected to Arduino UNO R4 WiFi GND
DC Power Source
- Positive connected to Rocker Switch 1
- Ground connected to STEPPER DRIVER GND and Arduino UNO R4 WiFi GND
Rocker Switch
- 1 connected to DC Power Source Positive
- 2 connected to STEPPER DRIVER ENA +, VCC, DIR+, PUL +
Documented Code
/*
* This Arduino sketch controls a stepper motor using a rotary encoder and a
* potentiometer. The rotary encoder sets the position and direction of the
* stepper motor, while the potentiometer adjusts the speed. Pressing the
* rotary encoder button enables fine movements. All actions are printed to
* the serial monitor for debugging purposes. The motor will not move unless
* the rotary encoder is turned clockwise or counter-clockwise.
*/
// Pin definitions
const int ENA_PIN = 4; // Connected to D4 on Arduino
const int DIR_PIN = 3; // Connected to D3 on Arduino
const int PUL_PIN = 2; // Connected to D2 on Arduino
const int ENCODER_CLK_PIN = 7; // Connected to D7 on Arduino
const int ENCODER_DT_PIN = 5; // Connected to D5 on Arduino
const int ENCODER_SW_PIN = 6; // Connected to D6 on Arduino
const int POT_PIN = A0; // Connected to A0 on Arduino
// Variables
int lastEncoderState = LOW;
int currentEncoderState;
int encoderValue = 0;
int potValue = 0;
int motorSpeed = 0;
bool fineMovement = false;
bool lastButtonState = HIGH; // Initial state is HIGH because of pull-up resistor
int lastEncoderValue = 0;
bool lastFineMovement = false;
int lastMotorDirection = LOW;
unsigned long lastDebounceTime = 0; // For debouncing
const unsigned long debounceDelay = 50; // Debounce delay in milliseconds
// Constants
const int STEPS_PER_DETENT = 20; // Steps per detent in normal mode
const int FINE_STEPS_PER_DETENT = 5; // Steps per detent in fine movement mode
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize pins
pinMode(ENA_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(PUL_PIN, OUTPUT);
pinMode(ENCODER_CLK_PIN, INPUT);
pinMode(ENCODER_DT_PIN, INPUT);
pinMode(ENCODER_SW_PIN, INPUT_PULLUP); // Use internal pull-up resistor
pinMode(POT_PIN, INPUT);
// Enable the stepper driver
digitalWrite(ENA_PIN, LOW);
// Test direction pin
digitalWrite(DIR_PIN, LOW); // Set to counter-clockwise
delay(2000); // Wait for 2 seconds
digitalWrite(DIR_PIN, HIGH); // Set to clockwise
delay(2000); // Wait for 2 seconds
// Debugging statements
Serial.println("Setup complete. Waiting for input...");
}
void loop() {
// Read the rotary encoder with debouncing
int reading = digitalRead(ENCODER_CLK_PIN);
if (reading != lastEncoderState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != currentEncoderState) {
currentEncoderState = reading;
if (digitalRead(ENCODER_DT_PIN) != currentEncoderState) {
encoderValue += fineMovement ? FINE_STEPS_PER_DETENT : STEPS_PER_DETENT;
} else {
encoderValue -= fineMovement ? FINE_STEPS_PER_DETENT : STEPS_PER_DETENT;
}
}
}
lastEncoderState = reading;
// Read the potentiometer
potValue = analogRead(POT_PIN);
motorSpeed = map(potValue, 0, 1023, 200, 1000); // Adjusted range for motor speed
// Check if the encoder button is pressed with debouncing
int encoderButtonState = digitalRead(ENCODER_SW_PIN);
if (encoderButtonState != lastButtonState) {
if ((millis() - lastDebounceTime) > debounceDelay) {
if (encoderButtonState == LOW) {
fineMovement = !fineMovement;
}
}
lastDebounceTime = millis();
}
lastButtonState = encoderButtonState;
// Set motor direction
int motorDirection = (encoderValue > 0) ? HIGH : LOW;
digitalWrite(DIR_PIN, motorDirection);
// Move the motor only if encoder value has changed
if (encoderValue != 0) {
int stepsToMove = abs(encoderValue);
for (int i = 0; i < stepsToMove; i++) {
digitalWrite(PUL_PIN, HIGH);
delayMicroseconds(motorSpeed);
digitalWrite(PUL_PIN, LOW);
delayMicroseconds(motorSpeed);
}
encoderValue = 0; // Reset encoder value after moving the motor
}
// Print changes