Bipolar Stepper Motor code/hardware used to work, but no longer does.

Hi all,

This is my first post on the forum, but I've been reading a fair bit on here for a while. And I've been avoiding posting anything until I've gotten desperate, but I'm pretty much there now.

So here's the problem I'm having:

For context the project is a camera slider. Please find attached an image of the wiring diagram, and below is a copy of the full code used with as many comments as I could add to help with understanding the madness.

// libraries
#include <AccelStepper.h>


/*Control Buttons*/
//declare all push buttons to pins.
const int btn1 = 8; // moves motor in one direction - see case 1
const int btn2 = 9; // moves motor in opposite direction to case 1 - see case 2
const int btn3 = 10; // logs current position value to start position - see case 3
const int btn4 = 11; // logs current position to end position - see case 4
const int btn5 = 12; // activates continuous movement of motor between start and end position - see case 5 and "the simplest button switch" code

//create containers to track button state (low or high). Not constant so value can change at the push and release of a button.
int btn1State = 0;
int btn2State = 0;
int btn3State = 0;
int btn4State = 0;
int btn5State = 0; // combines with "the simplest push button switch later

// declare 'mode' to contain and trigger switch.case functions
int mode = 0;


/*Speed Control - Pot*/
//Speed Control
int pot = 0; // declaring the linear slider
long highSpeed; // used to hold the high speed value of the stepper motor
long lowSpeed; // used to hold the high speed value of the stepper motor


/**********Stepper Setup**********/
//declare all STEPPER motor wires to pins.
const int PUL = 2;
const int DIR = 3;
const int ENBL = 4;

AccelStepper STEPPER (1, PUL, DIR); // Defining Stepper Motor 1 - Driver, PUL - Pulse, DIR - Direction
long motorSpeed = 0; // stores the stepping frequency of the motor driven by the potentiometer

long CURRENTpos = 0; // keeps track of the current position of the slider
long STARTpos = 0; // used to log the desired start position with btn3
long ENDpos = 0; // used to log the desired end position with btn4




void setup() { 
  Serial.begin (9600); // starts up serial com to track code state

  /*Control Buttons*/
  //declare push buttons are inputs.
  pinMode (btn1, INPUT);
  pinMode (btn2, INPUT);
  pinMode (btn3, INPUT);
  pinMode (btn4, INPUT);
  pinMode (btn5, INPUT);


  /*Speed Control - Pot*/
  // declaring A0 (pot) as an input
  pinMode (A0, INPUT);

}

void loop() { 

  /*Pot Speed Control*/
  highSpeed = 25600; // high speed value
  lowSpeed = 2000; // low speed value


  /*Stepper Setup*/
  pot = analogRead (A0);
  //Stepper settings refering back to pre-void setup data
  motorSpeed = map(pot, 0, 1023, lowSpeed, highSpeed); // mapping pot to desired motor speeds

  /* below was creating a "deadzone" for the potentiometer, but this was removed for simplicity. It did work well enough though.
    //  if (motorSpeed > (highSpeed * 0.99)) { // high speed deadzone
    //    motorSpeed = highSpeed ;
    //  }
    //  if (motorSpeed < (highSpeed * 0.03)) { // low speed deadzone
    //    motorSpeed = lowSpeed ;
    //  }
  */

  STEPPER.setSpeed (motorSpeed); // initiating stepper speed
  Serial.print ("Motor Speed = "); // keeping track of stepper speed
  Serial.println (motorSpeed);


  //preparing button pins to be monitored
  btn1State = digitalRead (btn1);
  btn2State = digitalRead (btn2);
  btn3State = digitalRead (btn3);
  btn4State = digitalRead (btn4);

  //btn5State
  if (digitalRead(btn5) == true) { // the simplest button switch. Allows btn5State to switch between HIGH and LOW at the push/toggle of a button.
    btn5State = !btn5State;
    digitalWrite (btn5, btn5State);
  } while (digitalRead (btn5) == true);
  Serial.print ("btn5State = ");
  Serial.println (btn5State);


  // checking the state of each button to determine what 'mode' should be.
  if (btn1State == HIGH) {
    mode = 1;
    
  }
  else if (btn2State == HIGH) {
    mode = 2;
   
  }
  else if (btn3State == HIGH) {
    mode = 3;
    
  }
  else if (btn4State == HIGH) {
    mode = 4;
    
  }
  else if (btn5State == HIGH) {
    mode = 5;
    
  } else {
    mode = 0;
    
  }


  Serial.print ("CURRENTpos = "); // keeping track of current position before a case is activated
  Serial.println (CURRENTpos);


  /**********Modes - functions**********/
  // switch.case action, depending on 'mode' an action will execute
  switch (mode) {
      break;
    case 0: // no instruction the motor to ensure there's no accidental movement. Not really necassary...
      Serial.println ("CASE = 0");
      break;

    case 1:
      //  Serial.println ("CASE = 1"); // MANUAL CW rotation - moves the motor clockwise a set number of steps
      STEPPER.setSpeed  (motorSpeed);
      STEPPER.setAcceleration  (motorSpeed);
      CURRENTpos = (CURRENTpos + 1000);
      STEPPER.runToNewPosition (CURRENTpos);
      STEPPER.runSpeed();
      Serial.print ("Case 1 CURRENTpos = ");
      Serial.println (CURRENTpos);
      break;

    case 2:
      // Serial.println ("CASE = 2"); // MANUAL CCW rotation - moves the motor counter clockwise a set number of steps
      STEPPER.setSpeed  (motorSpeed);
      STEPPER.setAcceleration  (motorSpeed);
      CURRENTpos = (CURRENTpos - 1000);
      STEPPER.runToNewPosition (CURRENTpos);
      STEPPER.runSpeed();
      Serial.print ("Case 2 CURRENTpos = ");
      Serial.println (CURRENTpos);
      break;

    case 3:
      //   Serial.println ("CASE = 3"); // MANUAL start position - logs the current position to start position
      STARTpos = CURRENTpos;
      Serial.print ("Case 3 STARTpos = ");
      Serial.println (STARTpos);
      STEPPER.run();
      break;

    case 4:
      //   Serial.println ("CASE = 4"); // MANUAL end position - logs the current position to end position
      ENDpos = CURRENTpos;
      Serial.print ("Case 4 ENDpos = ");
      Serial.println (ENDpos);
      STEPPER.run();
      break;

    case 5:
      //   Serial.println ("CASE = 5"); // Backwards and Forwards - moves the motor back and forward between the start and end postitions
      Serial.print ("Case 5 STARTpos = ");
      Serial.println (STARTpos);
      STEPPER.setSpeed  (motorSpeed);
      STEPPER.setAcceleration  (motorSpeed);
      STEPPER.runToNewPosition (STARTpos);
      STEPPER.run();
      Serial.print ("Case 5 ENDpos = ");
      Serial.println (ENDpos);
      STEPPER.runToNewPosition (ENDpos);
      STEPPER.run();
      break;
  }


  // FIN
}

So onto the issue.

I've setup a NEMA 34 Stepper Motor (85BYGH450C-060) with a DQ86OMA Driver powered by a 60V PSU (connected only to the driver). I've connected the PUL, DIR, and ENBL pins to an Arduino UNO (and later an Elegoo Mega 2560 - budget was waning at this point). And there's a set of 5 push buttons with pull down resistors along with a button to hard reset the Arduino. A potentiometer is is also included to control the speed of the stepper. The UNO and MEGA have been powered through a USB cable to my PC.

This code was working flawlessly when everything was assembled on a breadboard. When a button was pressed the motor responded as expected. But after soldering all the circuits together on a prototyping PCB and linking all the components with longer wires to fit into the body of the slider, an intermittent problem has developed (not immediately however).

Initially after all the final wiring was completed the setup was working really well, as well as it did with the breadboard setup. But now only days later it only works 90% (or less) of the time. Everything in the serial monitor shows up as it used to, and everything triggers as expected in the monitor, but for some reason there's no response from the motor at all now.

see message below for further info - I ran out of characters

So the question is, does it sound I'm looking at a driver malfunction here, or is there something else wrong? It sounds to me like a hardware failure between the Driver and the Motor (my money is, and probably will be on the Driver), but I wanted to call on the experience of many before I throw more money at this problem.

I'd really appreciate any assistance, thanks for checking out this post, and sorry for the long and drawn out text!

2019-07-09 20_20_23-Camera Slider Wiring.fzz_ - Fritzing - [Breadboard View].png

It was working on the Arduino UNO, then I tried it on an Elegoo MEGA 2560 (changing the Board, Processor, and COM in the IDE) and it stopped working (when it initially was working on the MEGA in the breadboard stage), and it then only intermittently worked on the UNO, but has now stopped altogether. I've bought another Elegoo MEGA 2560 in case I broke the other two somehow, and fresh out of the box the motor is not responding, but the serial monitor is showing all the right outputs (as it was when everything was working).

Further troubleshooting steps I've taken are to check the integrity of the connections, wire joints, etc. with the continuity setting of a multi-meter which came back as all intact, and there aren't any short circuits in the system. I've tested all the buttons individually to check if they're producing HIGH or LOW values, and they're rock solid LOW without a press, and HIGH with a press. The PSU is creating the desired 60V to power the Driver (which is running at half its maximum output - the same as I was before), and the Driver is showing the green light so I presume it's doing okay for power.

I have however measured the voltage at the Driver input of the PUL, DIR, and ENBL connectors, and the DIR pins change between 4.5v and 0v (as expected), but there's only 0.05v going through the PUL connectors (perhaps this is a problem with something inside the Driver not allowing more voltage through?). I've also checked the integrity of the lines through the motor with the continuity setting on a multi-meter, and they're completely fine (only a sound between two sets of two of wires).

I've also tried this basic code to see if the motor will respond:

#include <AccelStepper.h>

const int PUL = 2;
const int DIR = 3;
const int ENBL = 4;

AccelStepper myStepper (1, PUL, DIR); // Defining Stepper Motor 1 - Driver, PUL - Pulse, DIR - Direction

void setup() {
  myStepper.setSpeed(5000);
  myStepper.setAcceleration(2000);
  
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.runToNewPosition(2000);
  myStepper.run();
  delay(500);

  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.runToNewPosition(0);
  myStepper.run();
  delay(500);
}

And nothing happened. But the serial monitor is showing "clockwise" and "counter clockwise" every couple of seconds as expected.

AlexF16:
This code was working flawlessly when everything was assembled on a breadboard. When a button was pressed the motor responded as expected. But after soldering all the circuits together on a prototyping PCB and linking all the components with longer wires to fit into the body of the slider, an intermittent problem has developed (not immediately however).

Initially after all the final wiring was completed the setup was working really well, as well as it did with the breadboard setup. But now only days later it only works 90% (or less) of the time. Everything in the serial monitor shows up as it used to, and everything triggers as expected in the monitor, but for some reason there's no response from the motor at all now.

All of that strongly suggests a construction problem - which can be hard to pinpoint. The statement "was working really well, as well as it did with the breadboard setup" suggests that the PCB design is correct.

With a Nema 34 motor there are probably high currents flowing - if they are going through an inadequate track on a PCB that could be the cause of the problem.

Something simple like a poorly soldered joint is another possibility.

And it may be that a poor connection between the stepper driver and the motor has caused the driver to fry - they don't like being separated from their motor when powered up - even for a very brief interval.

Can you create a simple breadboard system with a short program to verify that the stepper and motor are in god condition?

...R

I don't see a signal return (ground) wire from motor driver back to Mega.

Thanks Robin. In terms of the connections between the components, there aren't any PCB's (at least ones that I've added) between the Arduino to the Motor. It's just wires between the Arduino and the Driver, and from the Driver to the Motor.

Something that may help is the driver is pushing out 3.5A on the setting I've been using, and I have been down to 2.4A. I'm no electrical engineer so I don't know if that's a lot of amps or a few amps for the hardware being used, but combined with the 60V that's about 210W so it sounds like a lot of power.

Perhaps it's just a really weak connection between the Driver and Motor like you said. I added a response in before and I have tested the Driver and Motor with a very basic program, and the motor didn't spin up unfortunately.

And now looking back at the wires, it turns out I've been using woefully inadequate wires for the connection between the Drive and Motor. I've been using 20AWG wires rated for 12V / 5A, and considering it's pushing 60V / 3.5A (or up to 7A) the wires are clearly not strong enough which could explain the "it used to work" situation. I should be using 10 AWG wiers apparently, so I'll replace these wires with some mains 240V wires and see if that either fixes the problem or if the Driver is dead entirely.

Does that sound like the culprit to you? I know I'm the one who did it, but let's blame the wires :stuck_out_tongue:

This is why I should have taken up electronics in school! I'll post an update if the problem persists or is fixed in the next couple of days. But let me know if you think I'm missing something else before I break more hardware. Thanks for the assistance so far!

I have ordered a new Driver for £50, but I'm not giving up on this one just yet if I can send the new one back for a refund.

JCA79B - Sorry about that, Fritzing didn't have the PSU or Driver I was using. The VCC and Ground connectors link back to the 60V PSU. And the (-) wires from the DIR, PUL, and ENBL connectors are all linked together and connected to the Ground connector of the PSU. So everything is Grounded, I just failed to show it on the diagram - I should have put some wires and notes in to explain that better.

The DIR, PUL, and ENBL signals don't come from the PSU, they come from the Mega, do you have a ground wire from the driver board to the Mega GND?

AlexF16:
And now looking back at the wires, it turns out I've been using woefully inadequate wires for the connection between the Drive and Motor. I've been using 20AWG wires rated for 12V / 5A, and considering it's pushing 60V / 3.5A (or up to 7A) the wires are clearly not strong enough

I think you are a bit mixed up there.

If the wire can take 5amps at 12v it can almost certainly take 5 amps at 60v. The voltage limit is determined by the insulation and most wires will be safe for use with a few hundred volts (but don't test them at dangerous voltages, just because I said so :slight_smile: )

What I was concerned about was the possibility that you were passing the motor current through a very flimsy copper track on a PCB.

...R

JCA79B - I'm well aware the DIR, PUL, and ENBL signals come from the Mega, hence why they're written into the code as such, and I specified the negative terminals are running to the PSU ground. I don't think there's a need to wire them to the ground of the Arduino, I thought since they're all going to the same place ultimately so that wasn't a concern.

Robin - Sorry about that, so when it comes to wires it's more about the amperage than the voltage? So I guess we're looking at a dead driver then... that's annoying.

So when does voltage become a concern? Is it more of a danger to chips and other modules? Sorry for the extra questions!

Thanks,

Alex

AlexF16:
So when does voltage become a concern? Is it more of a danger to chips and other modules? Sorry for the extra questions!

I can think of 3 issues.

There is some voltage level (I don't know what it is) above which electricity poses a risk of injury or death.

Most electronic components will have a maximum voltage that they can function at. This will be clearly stated in the product datasheet.

The purpose of insulation is to prevent the electricity in a wire from coming into contact with other things or with people. The voltage at which insulation fails is usually a great deal higher than either of the other two.

...R

Awesome, thanks for the insight!

Also I found the source of the problem, and you were basically right. There was a dodgy connection in the head of the breadboard style pin of the PUL connection, which of course means the pulse wasn't making it to the driver.

One thing that alerted me to this was the new driver which has a testing function that doesn't need an input through the pulse pins:

Knowing that the driver was working, the motor was working, and the Arduino was working meant either the code or connections must be wrong. And since we verified the code was fine before, I went around retesting the connections. So the head of that pin must have loosened up over time.

That new driver is really cool piece of kit, so I'll sell of the one I was previously using to compensate for the cost

Anyway, thank you so much for the help through all of that. With any luck this will prevent me from coming onto the forum for silly connection issues like this again!

All the best,

Alex