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.
/*
* 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