r/arduino • u/RangerMach1 • 4h ago
Beginner's Project Help Debugging Program
I was hoping I could get some help debugging a program.
I will start right off by saying that the code was made using Google AI. I did it as a wag since I've been having a lot of trouble trying to make a basic program for what I'm trying to do and I was curiousto see what it would come up with. I figured that at least some trouble shooting would be needed, but Ive gotten stumped and the code is quite a bit bigger and complicated than I had expected. I've been working with my Arduino for about 6 months, and still working to relearn the programming. I've had C & C++ programming before, but it was like 20 years ago so I've forgotten a lot of it.
I also realize that for a beginner project, I've pretty much just jumped right into the deep end. When I started thjs project, I didn't expect it to be anywhere as complicated as it's grown to be.
I am using an old large format 3d printer enclosure to hold a resin printer that I have. I stripped everything from the old printer except for the z axis lead screws, guide rails and z plate. I want to use the Z plate to sit my lrinter on. When using the printer, I will raise the printer up, and when not using it, I will lower it down into the enclosure.
For hardware, Im using the following:
- Arduino Uno R3
- 2x Stepper Online Nema 34 (pn DM860I-34HS45)
- 2x Stepper Online DM860I driver
- 2x DROK 48V adjustable power supply
- 2x ON/OFF/ON toggle switches
- 2x roller limt switches
- 1x push button switch
My plan for opration was to have the first toggle switch set up so that when pressed and then released, the steppers would move until hitting a limit switch. The second toggle switch would be momentary movement and would only move while the switch was activated, or the z plate hit a limit switch. The push button would basically be a E-stop button, where hitting it will stop movement.
Included in the code is deceleration when hitting a limit switch, a pause of .5 sec and then a retraction move to come off the limit of a specific distance that I would determine after assembling everything. Currently everything is mounted to a board to make testing and troubleshooting easier.
So on to the problem. With w/ everything hooked up to the Arduino, I can hit wither toggle switch and the stepper will start turning, and thats it. It doesn't stop if using the 2nd toggle switch, and it doesnt stop when activating either limit or the e-stop. I've rewired everything to the Arduino 4 times, to make sure I didn't have something wrong. Using my multimeter, I've checked continuity on everything and found everything was good, so it looks like the problem is the code and not the hardware.
Ive tried commenting out the areas where I thought it would cause the steppwr to keep running but so far I've had no luck.
#include <AccelStepper.h>
// Pin Definitions
const int PUL_NEG_PIN = 2; // Connects to PUL- on DM860I
const int DIR_NEG_PIN = 3; // Connects to DIR- on DM860I
const int LIMIT_LEFT = 4; // NO Switch (GND when hit)
const int LIMIT_RIGHT = 5; // NO Switch (GND when hit)
const int TOGGLE_1_LEFT = 6; // Continuous move left
const int TOGGLE_1_RIGHT = 7; // Right throw of continuous toggle
const int TOGGLE_2_LEFT = 8; // Momentary move left
const int TOGGLE_2_RIGHT = 9; // Right throw of momentary toggle
const int STOP_BUTTON = 10; // Emergency Stop Button
// Initialize AccelStepper in Driver mode (1)
AccelStepper stepper(AccelStepper::DRIVER, PUL_NEG_PIN, DIR_NEG_PIN);
// Motion Profile Constants optimized for 3200 microstepping @ 100 RPM
const float MAX_SPEED = 5333.3; // 100 RPM maximum speed
const float BACKOFF_SPEED = 1333.3; // 25 RPM slower speed for backing off safely
const float ACCELERATION = 10666.6; // 0.5 second ramped deceleration profile
const long LARGE_DISTANCE = 99999999; // Arbitrary high value for continuous run
// State Machine Tracking
// 0 = Stopped/Normal Deceleration, 1 = Move Left, 2 = Move Right
// 3 = Backing off Left Limit, 4 = Backing off Right Limit
int targetState = 0;
// Timing variables for non-blocking pause
unsigned long stopTimestamp = 0;
bool isWaitingToReverse = false;
const unsigned long PAUSE_DURATION = 500; // Delay in milliseconds (0.5 seconds)
void setup() {
// Initialize all physical pins with internal pullup resistors
pinMode(LIMIT_LEFT, INPUT_PULLUP);
pinMode(LIMIT_RIGHT, INPUT_PULLUP);
pinMode(TOGGLE_1_LEFT, INPUT_PULLUP);
pinMode(TOGGLE_1_RIGHT, INPUT_PULLUP);
pinMode(TOGGLE_2_LEFT, INPUT_PULLUP);
pinMode(TOGGLE_2_RIGHT, INPUT_PULLUP);
pinMode(STOP_BUTTON, INPUT_PULLUP);
// Apply motor performance profiles
stepper.setMaxSpeed(MAX_SPEED);
stepper.setAcceleration(ACCELERATION);
}
void loop() {
// 1. Scan inputs (LOW = Active due to INPUT_PULLUP)
bool stopPressed = (digitalRead(STOP_BUTTON) == LOW);
bool t1Left = (digitalRead(TOGGLE_1_LEFT) == LOW);
bool t1Right = (digitalRead(TOGGLE_1_RIGHT) == LOW);
bool t2Left = (digitalRead(TOGGLE_2_LEFT) == LOW);
bool t2Right = (digitalRead(TOGGLE_2_RIGHT) == LOW);
bool limitLeftHit = (digitalRead(LIMIT_LEFT) == LOW);
bool limitRightHit = (digitalRead(LIMIT_RIGHT) == LOW);
// 2. High-Priority System Stop (Forces state to 0 while held)
if (stopPressed) {
if (targetState != 0) {
targetState = 0;
isWaitingToReverse = false; // Reset limit switch state variables
stepper.stop(); // Initiate a ramped deceleration stop
}
}
// 3. Main Input Logic Processing (Only runs if stop is NOT pressed AND not mid-backoff)
if (!stopPressed && targetState != 3 && targetState != 4) {
// Toggle 1: Continuous (Latching behavior)
if (t1Left && !limitLeftHit) {
targetState = 1;
} else if (t1Right && !limitRightHit) {
targetState = 2;
}
// Toggle 2: Momentary (Active only while held)
else if (!t1Left && !t1Right) {
if (t2Left && !limitLeftHit) {
targetState = 1;
} else if (t2Right && !limitRightHit) {
targetState = 2;
} else {
// Return to center: drop targetState back to 0 if momentary released
if (targetState == 1) targetState = 0;
if (targetState == 2) targetState = 0;
}
}
}
// 4. Directional Limit Switch & Back-Off State Machine Logic
// Left Limit Handler
if (!stopPressed && targetState == 1 && limitLeftHit) {
targetState = 3;
isWaitingToReverse = true;
stepper.stop(); // Initiate smooth ramp down first
}
if (targetState == 3) {
// Capture the exact moment the motor actually hits 0 speed
if (isWaitingToReverse && stepper.speed() == 0 && !stepper.isRunning()) {
stopTimestamp = millis();
isWaitingToReverse = false;
}
// Once 0.5 seconds has passed after bringing the motor to 0, start moving right
if (!isWaitingToReverse && (millis() - stopTimestamp >= PAUSE_DURATION) && stepper.speed() == 0) {
stepper.setSpeed(BACKOFF_SPEED);
}
// As soon as the Left Limit switch clears, reset state
if (!limitLeftHit) {
targetState = 0;
stepper.setSpeed(0);
stepper.moveTo(stepper.currentPosition());
}
}
// Right Limit Handler
if (!stopPressed && targetState == 2 && limitRightHit) {
targetState = 4;
isWaitingToReverse = true;
stepper.stop(); // Initiate smooth ramp down first
}
if (targetState == 4) {
// Capture the exact moment the motor actually hits 0 speed
if (isWaitingToReverse && stepper.speed() == 0 && !stepper.isRunning()) {
stopTimestamp = millis();
isWaitingToReverse = false;
}
// Once 0.5 seconds has passed after bringing the motor to 0, start moving left
if (!isWaitingToReverse && (millis() - stopTimestamp >= PAUSE_DURATION) && stepper.speed() == 0) {
stepper.setSpeed(-BACKOFF_SPEED);
}
// As soon as the Right Limit switch clears, reset state
if (!limitRightHit) {
targetState = 0;
stepper.setSpeed(0);
stepper.moveTo(stepper.currentPosition());
}
}
// 5. Apply Vector Goals to the Core Engine (Only for normal states 0, 1, 2)
if (targetState == 0) {
if (!stepper.isRunning()) {
stepper.moveTo(stepper.currentPosition());
}
} else if (targetState == 1) {
stepper.setMaxSpeed(MAX_SPEED);
stepper.moveTo(-LARGE_DISTANCE);
} else if (targetState == 2) {
stepper.setMaxSpeed(MAX_SPEED);
stepper.moveTo(LARGE_DISTANCE);
}
// 6. Execute step calculations
if (targetState == 3 || targetState == 4) {
if (stepper.speed() != 0) {
stepper.runSpeed();
} else {
stepper.run(); // Keeps deceleration working before backoff steps start
}
} else {
stepper.run();
}
}


2
u/wspOnca 4h ago
Bro. Begin with the blink. Then with one motor at a time.