Hello,
I'm having problems with functioning of stepper motor.
Im making a gearselector, Forward-Neutral_Reverse.
With 3 pushbuttons and 3 control led's
Components:
Oled 0.91" screen.
Arduino uno
DRV8825
42SHDC3025-24B motor
3 Pushbuttons
3 Leds
External powersource (12V) for powering motor.
Breadboard powersupply
1 capacitor 470uf (a cross feed motor.
What i want it to do:
After homing, move to neutral.
And then be able to react to wich pushbutton is pressed, and move motor to that fixed location.
What it does now:
It home's motor speed is good, no weird noices, everything runs nice.
Max_speed and Max_accelration, have effect on homing settings.
But when i press button for example "Reverse" motor moves but very slowly and stutters.
All buttons and leds are doing what asked, screen is update to current location.
The only thing that does not works the way i expected is the motor speed.
No matter how i set Max_speed and Max_ acceleration, this has no effect.
I tryed changing stepperdriver, but i dont think thats the issue. Because motor works fine while homing.
So i'm kinda stuck now, could use some help.
Everything is connected as seen in Pin Definitions, drv8825 reset_sleep to 5v, fault not connected, gnd to arduino.
Thanks in advance
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <AccelStepper.h>
// Pin definitions
#define BUTTON_FORWARD_PIN 6
#define BUTTON_NEUTRAL_PIN 7
#define BUTTON_REVERSE_PIN 8
#define LIMIT_SWITCH_PIN 9
#define RESET_PIN 1
#define LED_FORWARD_PIN 3
#define LED_NEUTRAL_PIN 2
#define LED_REVERSE_PIN 10
// OLED Display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Stepper motor
#define STEP_PIN 4
#define DIR_PIN 5
AccelStepper stepper(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
// Gear positions
enum GearPosition {NEUTRAL, FORWARD, REVERSE};
long initial_homing = 0;
GearPosition currentPosition = REVERSE;
const int stepsPerRevolution = 200;
// States for LEDs and display
const int ledPins[] = {LED_FORWARD_PIN, LED_NEUTRAL_PIN, LED_REVERSE_PIN};
bool homingComplete = false;
void setup() {
// Initialize serial monitor
Serial.begin(115200);
// Initialize pins
pinMode(BUTTON_FORWARD_PIN, INPUT_PULLUP);
pinMode(BUTTON_NEUTRAL_PIN, INPUT_PULLUP);
pinMode(BUTTON_REVERSE_PIN, INPUT_PULLUP);
pinMode(LIMIT_SWITCH_PIN, INPUT_PULLUP);
pinMode(RESET_PIN, INPUT_PULLUP);
for (int i = 0; i < 3; i++) {
pinMode(ledPins[i], OUTPUT);
}
ledTest();
// Initialize the stepper motor
stepper.setMaxSpeed(1000);
stepper.setAcceleration(700);
//Serial.println("Starting homing process..."); // Homing process
while (!digitalRead(LIMIT_SWITCH_PIN) == LOW) { // Make the Stepper move CW until the switch is deactivated
stepper.moveTo(initial_homing);
stepper.run();
initial_homing--;
delay(5);
}
//if (digitalRead(LIMIT_SWITCH_PIN) == LOW) { // When the limit switch is LOW, move CCW
//stepper.moveTo(initial_homing);
//stepper.run();
//initial_homing++; // Moving in the CCW direction (decreasing position)
//delay(5);
//serial.printIn("Neutral");
//}
//stepper.stop();
currentPosition = 0;
// Optionally, move to neutral position after homing
moveStepperToPosition(NEUTRAL);
// Wait for the motor to reach neutral position
while (stepper.distanceToGo() != 0) {
stepper.run();
}
// Print "ready neutral" after homing and reaching neutral
//Serial.println("ready neutral");
// Initialize OLED display
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Stay in infinite loop if OLED fails to initialize
}
display.display();
delay(2000); // Wait for a second for startup
// Update display initially
homeGearShift();
updateDisplay();
}
void ledTest() {
// Perform LED test by lighting up LEDs in sequence
digitalWrite(LED_FORWARD_PIN, HIGH);
delay(500); // LED on for 500 ms
digitalWrite(LED_FORWARD_PIN, LOW);
digitalWrite(LED_NEUTRAL_PIN, HIGH);
delay(500); // LED on for 500 ms
digitalWrite(LED_NEUTRAL_PIN, LOW);
digitalWrite(LED_REVERSE_PIN, HIGH);
delay(500); // LED on for 500 ms
digitalWrite(LED_REVERSE_PIN, LOW);
}
void loop() {
// Check the limit switch to set home position if not already done
if (digitalRead(RESET_PIN) == LOW) {
resetHoming();
}
// After homing, limit switch triggers are ignored (homingComplete is true)
if (!homingComplete) {
shiftToNeutral();
Serial.println("Neutral");
return; // Do nothing until homing is completed
}
// Handle button presses for shifting gears
if (digitalRead(BUTTON_FORWARD_PIN) == LOW) {
shiftToForward();
Serial.println("Forward");
delay(500);
}
if (digitalRead(BUTTON_NEUTRAL_PIN) == LOW) {
shiftToNeutral();
//stepper.run();
Serial.println("Neutral");
delay(500);
}
if (digitalRead(BUTTON_REVERSE_PIN) == LOW) {
shiftToReverse();
Serial.println("Reverse");
delay(500);
}
//if (digitalRead(LIMIT_SWITCH_PIN) == LOW) {
//Serial.printIn("Neutral");
// Update the stepper motor position continuously
stepper.run();
// Update display and LEDs based on current position
updateDisplay();
}
void shiftToForward() {
if (currentPosition != FORWARD) {
moveStepperToPosition(FORWARD);
currentPosition = FORWARD;
}
}
void shiftToNeutral() {
if (currentPosition != NEUTRAL) {
moveStepperToPosition(NEUTRAL);
currentPosition = NEUTRAL;
}
}
void shiftToReverse() {
if (currentPosition != REVERSE) {
moveStepperToPosition(REVERSE);
currentPosition = REVERSE;
}
}
void moveStepperToPosition(GearPosition position) {
// Define the stepper motor position for each gear
int targetPosition = 0;
switch (position) {
case FORWARD:
targetPosition = 100; // example position for Forward
break;
case REVERSE:
targetPosition = -100; // example position for Reverse
break;
case NEUTRAL:
targetPosition = 0; // example position for Neutral
break;
}
stepper.moveTo(targetPosition);
}
void homeGearShift() {
while (digitalRead(LIMIT_SWITCH_PIN) == LOW) { // Limit switch is LOW (not pressed)
stepper.moveTo(initial_homing);
stepper.run();
initial_homing--;
delay(5); // Small delay to prevent excessive speed
}
stepper.stop();
//currentPosition = -100;
moveStepperToPosition(NEUTRAL);
while (stepper.distanceToGo() != 0){
stepper.run();
}
// Serial.println("Ready Neutral");
homingComplete = true;
digitalWrite(LED_NEUTRAL_PIN, HIGH);
digitalWrite(LED_FORWARD_PIN, LOW);
digitalWrite(LED_REVERSE_PIN, LOW);
//digitalWrite(BUTTON_NEUTRAL_PIN, LOW);
//display.print("Ready Neutral");
//updateDisplay();
}
void resetHoming() {
// Reset the homing state and allow limit switch to be used again
homingComplete = false;
initial_homing = -1; // Reset the homing counter
currentPosition = NEUTRAL;
// Move stepper to re-home position (go to limit switch again)
stepper.setCurrentPosition(0); // Reset current position
homeGearShift();
}
void updateDisplay() {
display.clearDisplay();
// Set text size
display.setTextSize(3); // Set text size to 2 (larger)
// Set text color
display.setTextColor(SSD1306_WHITE);
// Get the width of the text to center it
int16_t x1, y1;
uint16_t textWidth = 0;
if (homingComplete) {
//display.getTextBounds("Neutral Ready", 0, 0, &x1, &y1, &textWidth, NULL);
// display.setCursor((SCREEN_WIDTH - textWidth) / 2, SCREEN_HEIGHT / 2 - 10); // Center horizontally and position vertically
//display.print("Neutral Ready");
//} else {
// Display gear position
switch (currentPosition) {
case FORWARD:
display.getTextBounds("Forward", 0, 0, &x1, &y1, &textWidth, NULL);
display.setCursor((SCREEN_WIDTH - textWidth) / 2, SCREEN_HEIGHT / 2 - 10); // Center horizontally and position vertically
display.print("Forward");
digitalWrite(LED_FORWARD_PIN, HIGH);
digitalWrite(LED_NEUTRAL_PIN, LOW);
digitalWrite(LED_REVERSE_PIN, LOW);
break;
case REVERSE:
display.getTextBounds("Reverse", 0, 0, &x1, &y1, &textWidth, NULL);
display.setCursor((SCREEN_WIDTH - textWidth) / 2, SCREEN_HEIGHT / 2 - 10); // Center horizontally and position vertically
display.print("Reverse");
digitalWrite(LED_FORWARD_PIN, LOW);
digitalWrite(LED_NEUTRAL_PIN, LOW);
digitalWrite(LED_REVERSE_PIN, HIGH);
break;
case NEUTRAL:
display.getTextBounds("Neutral", 0, 0, &x1, &y1, &textWidth, NULL);
display.setCursor((SCREEN_WIDTH - textWidth) / 2, SCREEN_HEIGHT / 2 - 10); // Center horizontally and position vertically
display.print("Neutral");
digitalWrite(LED_FORWARD_PIN, LOW);
digitalWrite(LED_NEUTRAL_PIN, HIGH);
digitalWrite(LED_REVERSE_PIN, LOW);
break;
//case FORWARD:
//display.getTextBounds("Forward", 0, 0, &x1, &y1, &textWidth, NULL);
//display.setCursor((SCREEN_WIDTH - textWidth) / 2, SCREEN_HEIGHT / 2 - 10); // Center horizontally and position vertically
//display.print("Forward");
//digitalWrite(LED_FORWARD_PIN, HIGH);
//digitalWrite(LED_NEUTRAL_PIN, LOW);
//digitalWrite(LED_REVERSE_PIN, LOW);
// break;
}
}
// Update OLED display
display.display();
}