Arduino with Stepper driver and motor questions.

Hi everyone :slight_smile:

I am trying to run a arduino, stepper motor, with a stepper driver, I am using AccelStepper library, but im not questioning that individual library, and my concerns are focused on the physical connection of the setup and the sideeffects.

/////CODE logic/////
//I declare the AccelStepper library
#include <AccelStepper.h>

//Attach stepper to AccelStepper method
AccelStepper stepperA(AccelStepper::DRIVER, 5, 4); //Declare stepper A

//Setting speeds for stepper
stepperA.setMaxSpeed(200);
stepperA.setAcceleration(100);
stepperA.setSpeed(200);

//Run following constantly in Loop()
stepperA.run();

//Calling moveTo via serial command when the motor needs to run
stepperA.moveTo((long)gotoPos.toInt());

/////CODE logic end/////

Motor runs.... BUT there are several issues

  1. Steps are lost occationally, it seems to due to some kind of noise from the connected USB cable to PC, if motor power is ON, and im getting ready to plug in USB to Arduino Duemilanove
    and the cable touch the USB port, the motor jitter 1-2 steps in random direction and sometimes randomly afterwards.

USB cable is plain, and no ferrite beads are attached. I tried to attach a ferrite bead between the Stepper driver and motor, but no luck.

How do i overcome this obstacle?

  1. When plugging in the USB cable or starting Serial communication, the motor will run/jitter randomly CW and CCW for a finite amount of time until Serial connection is established. This ruins the motor positioning
    and i need to calibrate the steps after the program have initialized.

  2. I have read something about connecting Stepper driver reset to Arduino reset, so i did, and it prevents some of the constant stepper motor rotation when connecting/until serial is initialized, but is it the correct approach?

Hardware:

Power supply:
12V 2A (Motor)
5V 1A (Stepper logic)
USB to Microcontroller

Microcontroller:
Arduino Duemilanove

Driver:
(StepStick A4988 Stepper driver module)

Stepper motor:
(42BYGHW208)

Any leads on how to solve these issues would be very appriciated. Please do not hesitate to ask for any further information which could help identify the problems.

With sincere regards
Rune Jensen

You really need more than 12V for your stepper driver - chopper drivers rely on the supply voltage being higher
(usually a lot higher) than the motor's voltage drop at stationary. You motor at its rated current
will drop 12V already, so something like 18 or 24V would be more satisfactory to allow the chopper
to reach the desired current level.

As for the interference you do have common ground between Arduino and A4998? You are not trying
to power the Arduino from a motor supply?

Well, the motor functions quite nicely, but its just the interference or the incorrect implementation of the stepper motor/driver.

As a note, this is my first attempt for steppers, I have done a lot of research for it, but as english is not my native tongue, some of the technical terms may have slipped past me, maybe resulting in missing or incorrect implementation.

I have attached a schematic in the original post, and that exactly the setup i have right now, can you elaborate on the common ground and how that would be implemented in the current schematic?

The arduino is powered from USB
Driver logic is powered from 5V
Stepper motor is powered from 12V

I have some basic understanding on common ground, but im just afraid of blowing some components up, hence why im here :frowning:

R_Jensen:
Well, the motor functions quite nicely,

If it did you would not be asking questions here :slight_smile:

How many steps per second are you expecting the motor to move at?
Are you using full steps or microsteps?

Post your complete program.
And please use the code button </> so your code looks like this and is easy to copy to a text editor

...R
Stepper Motor Basics

Its running full step as pr the schematic attached. The motor have a minimal load, as it only moves a small 3D print. It moves 50 steps(90degree) whenever it moves. Im trying to accomplish 0.5 second for those 50 steps. But faster would also be nicer.

I dont have the full code Here. But Will post it later today. Apart from the mentioned codelogic described in the original post, there is not much happening, apart from some sensor work. But for completenes sake i Will post it later today.

As requested, here is the code

If you need the Stepper Motor to move, just issue a "85" command following the amount of steps

Ie.:
"851000" = 1000 steps CW
or
"85-1000" = 1000 steps CCW

#include <Wire.h>
#include <AccelStepper.h>
#include <Servo.h>
#include "Adafruit_TCS34725.h"

int laststepA = 0;

//Color sensor
//SDA A4
//SCL A5

uint16_t red, green, blue, clearc, colorTemp, lux;

int hopperServoPin =  12;         // control pin for hopper servo motor
int hopperTubeSensorPin =  10;    //pin for hopper tube sensor    ///////////////TODO: Assign the pin

Servo hopperServo; //Declare hopper servo

AccelStepper stepperA(AccelStepper::DRIVER, 5, 4); //Declare stepper A

Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_1X); //Declare Color sensor

String inData;        //Variable to store input received over serial
String header;        //Variable to hold the header of the received input over serial
String content;       //Variable to hold the header of the received input over serial
String gotoPos;       //Variable to store the position for the stepper to move to.

//Setup hopper servo parameters
int hopperControl = 0;

//Setup hopper tube sensor parameters
int hopperTubeSensor = 0;

//Setup hopper color sensor parameters
int hopperColorSensor = 0;

int maxSpeedA = 200;

int accelerationA = 100;

int speedA = 200;

int pauseProcess = 0; //Pause state variable


void setup() {
  //Prepare serial
  Serial.begin(9600);
  Serial.println("Communication :: Ready");
  delay(500);
  if (tcs.begin()) {
    Serial.println("0#90##");
  } else {
    Serial.println("0#91##");
    while (1);
  }

  //Set variables for steppers

  stepperA.setMaxSpeed(maxSpeedA);
  stepperA.setAcceleration(accelerationA);
  stepperA.setSpeed(speedA);

  hopperServo.attach(hopperServoPin);

  //  resetSteppersFromMemory();
  //digitalWrite(2,LOW); // Set Enable low
}

void loop() {
  //The run() function must be called frequently until the motor is in the desired position, after which time run() will do nothing.
  stepperA.run();


  Pause(); //Pause is called each cycle to pause the process if called.

  if (Serial.available() > 0) {
    readcommand();
  }

}
void readcommand() {
  while (Serial.available() > 0)
  {
    char recieved = Serial.read();
    inData += recieved;

    // Process message when new line character is recieved
    if (recieved == '\n')
    {
      //             Serial.print("Packet Received: ");
      Serial.println(inData);
      header += inData[0];
      header += inData[1];
      content += inData[2];
      content += inData[3];
      content += inData[4];
      content += inData[5];
      content += inData[6];

      //0 - Debugger                                 //Example: 0
      //81 - Set position A                          //Example: 81
      //82 - A end of movement command               //Example: 82
      //99 - Flow command


      //0 - Debugger
      if (inData[0] == '0') {
        Serial.print("Debugging disabled");
      }

      //13 - StepperA
      if (header == "14") {
        if (stepperA.distanceToGo() == 0)    {
          //gotoPos = concat(inData[2],inData[3],inData[4],inData[5]);
          gotoPos += inData[2];
          gotoPos += inData[3];
          gotoPos += inData[4];
          gotoPos += inData[5];
          gotoPos += inData[6];
          Serial.print("Spinning A: ");
          Serial.println((long)gotoPos.toInt());
          stepperA.moveTo((long)gotoPos.toInt());
        }
      }
      //71 - Hopper
      if (header == "71") {
        hopperControl = content.toInt(); hopperServo.write(hopperControl);
        Serial.println("0#71##");
      }

      //72 - Hopper Tube sensor
      if (header == "72") {
        Serial.print("0#72##"); Serial.println(hopperTubeSensor);
      }
      //73 - Hopper Color sensor
      if (header == "73") {

        tcs.getRawData(&red, &green, &blue, &clearc);
        //                colorTemp = tcs.calculateColorTemperature(r, g, b);
        //                lux = tcs.calculateLux(r, g, b);
        colorTemp = 123;
        lux = 222;

        uint32_t sum = clearc;
        float r, g, b;
        r = red; r /= sum;
        g = green; g /= sum;
        b = blue; b /= sum;
        r *= 256; g *= 256; b *= 256;
        Serial.print("0#73##"); Serial.print((int)r, HEX); Serial.print((int)g, HEX); Serial.println((int)b, HEX);
        r = 0;
        g = 0;
        b = 0;
      }

      //74  - Hopper Color sensor with feedback
      if (header == "74") {

        tcs.getRawData(&red, &green, &blue, &clearc);
        //                colorTemp = tcs.calculateColorTemperature(r, g, b);
        //                lux = tcs.calculateLux(r, g, b);
        colorTemp = 123;
        lux = 222;

        uint32_t sum = clearc;
        float r, g, b;
        r = red; r /= sum;
        g = green; g /= sum;
        b = blue; b /= sum;
        r *= 256; g *= 256; b *= 256;
        //                Serial.print("DEBUG: ");Serial.print(red);Serial.print(" - "); Serial.print(green); Serial.print(" - "); Serial.print(blue);Serial.print(" - ");Serial.println(clearc);
        //                Serial.print("DEBUG: ");Serial.print(r);Serial.print(" - "); Serial.print(g); Serial.print(" - "); Serial.print(b);Serial.print(" - ");Serial.println(sum);
        Serial.print("0#74##"); Serial.print((int)r, HEX); Serial.print((int)g, HEX); Serial.println((int)b, HEX);
        //Serial.print("0#99##");  Serial.println("10"); //Update Flow
        r = 0;
        g = 0;
        b = 0;

      }
      //75 - Hopper Color sensor LED OFF
      if (header == "79") {

      }


      //80 - Pause Process
      if (header == "80") {
        Serial.print("0#80##"); if (pauseProcess == 0) {
          pauseProcess = 1;
        } else {
          pauseProcess = 0;
        }
      }
      //Move absolute
      if (header == "81") {
        if (stepperA.distanceToGo() == 0)    {
          //gotoPos = concat(inData[2],inData[3],inData[4],inData[5]);
          gotoPos += inData[2];
          gotoPos += inData[3];
          gotoPos += inData[4];
          gotoPos += inData[5];
          gotoPos += inData[6];
          stepperA.moveTo((long)gotoPos.toInt());
          Serial.println("0#82##");

        }
      }

      //Move relative
      if (header == "85") {
        if (stepperA.distanceToGo() == 0)    {
          //gotoPos = concat(inData[2],inData[3],inData[4],inData[5]);
          gotoPos += inData[2];
          gotoPos += inData[3];
          gotoPos += inData[4];
          gotoPos += inData[5];
          gotoPos += inData[6];
          stepperA.move((long)gotoPos.toInt());
          Serial.println("0#85##");

        }
      }

      //Move relative
      if (header == "86") {
        if (stepperA.distanceToGo() == 0)    {
          //gotoPos = concat(inData[2],inData[3],inData[4],inData[5]);
          gotoPos += inData[2];
          gotoPos += inData[3];
          gotoPos += inData[4];
          gotoPos += inData[5];
          gotoPos += inData[6];
          stepperA.move((long)gotoPos.toInt());
          Serial.println("0#86##");

        }
      }

      //Clean buffers
      header = "";
      content = "";
      gotoPos = "";
      inData = "";
      red = 0;
      green = 0;
      blue = 0;
      clearc = 0;
      colorTemp = 0;
      lux = 0;
    }
  }

}

void Pause() {
  while (pauseProcess > 0) {
    if (Serial.available() > 0) {
      readcommand();
    }
  }
}

I wonder if your readCommand() function takes so long that the speed of repetition of loop() is not fast enough to make enough calls to stepperA.run() - that could be the cause of some missed steps.

Your code for receiving data is not robust. You check for at least one character in the input buffer and then expect to read several characters.

It is not a good idea to use Strings (capital S) in the small memory of an Arduino. It can cause memory corruption. It is much safer to use strings (small s).

The examples in Serial Input Basics are simple reliable ways to receive data - and they use strings (small s). There is also a parse example to illustrate how to convert ascii values to integers etc.

...R

Not calling run() often enough would slow down steps, not miss them. However expecting the motor
to accelerate/decelerate too fast will cause missed steps, the rotor has to acquire momentum fast enough
to keep up with the steps, and there is only a finite amount of torque available. In general if you want
a motor to do the fastest transitions from point to point you will need AccelStepper, or equivalent
library to ramp the velocity. The larger/heavier the load the more important this is.

MarkT - I am already using AccelStepper library.

Currently I have slowed down the speed of it for troubleshooting sake. So im not sure that speed is the issue at hand.

Also im calling the moveTo command once, so there is no serial reading anything at the point in time where the motor starts to move. I am aware of some of the coding issues and im glad you pointed out the string issue, which I didnt know about. Actually i check for 2 chars in header(except if its 0), then i buffer them using "inData" variable.

I havent run into any Serial issues, i also read out sensor data alongside the stepper(when stepper is idle).

Mind checking the schematic for errors, missing ground or improvement? :slight_smile:

Noone? :slight_smile:

R_Jensen:
MarkT - I am already using AccelStepper library.

Currently I have slowed down the speed of it for troubleshooting sake. So im not sure that speed is the issue at hand.

Does it still miss steps at lower speed?

Have you lowered the acceleration too - you need to experiment to find the maximum speed and maximum
acceleration your setup (under mechanical load) can actually attain. You then back off both a bit for reliability.

Not using microsteps will usually increase the probability of mis-stepping - unless the motor is well
damped mechnically. Resonance is the bane of stepper motors.

I have tried different speeds but to no avail. The fact that the motor can sit idle and step 1 step CW or CCW makes me believe that it would also happen during operation. Im looking for answers to mitigate just that. Do you Think shielded cables from the computer to the arduino would solve this and grounding all the powersources to the same ground would solve auch an issue?

R_Jensen:
I have tried different speeds but to no avail.

But not acceleration? Both are vital - set either too high and you will miss steps.

R_Jensen:
The fact that the motor can sit idle and step 1 step CW or CCW makes me believe that it would also happen during operation. Im looking for answers to mitigate just that.

Do you mean that the motor sometimes moves 1 step even though the Arduino does not ask it to move?

If so, make a pencil drawing showing how YOU have everything connected and post a photo of the drawing. It would also be a good idea to post a photo of your hardware - but that would not be a substitute for the pencil drawing.

Try this Simple Stepper Code and see what happens.

...R

Yes, as for the drawing, I have allready posted it in #1 post posted how everything is connected. I could take some hardware screenshots, but since the setup is quite simple I dont see benefit. I have asked alot of questions and have received 0 answers. I know hardware setup can be a pain to debug, but im sitting here posting stuff about things allready posted.

Im not trying to give everyone a hard time, but I just need to know how to remove what seems to be interference in the system. The code runs fine, nothing to it and it works as expected. I have tested this in a controlled environment, and it runs as it should on all parameters, but when running it full scale, the interference problems arose. I get that it could be due to longer cabling, and missing shielded cables or grounding issues, I just want to know how to properly implement that correctly, or hear any experience with similar issues. Also references to products which could solve this issue is also very welcome.

R_Jensen:
Yes, as for the drawing, I have allready posted it in #1 post posted how everything is connected.

IIRC the picture in your original post is from the Pololu web page. It would be great to see a drawing showing how YOU have implemented it - especially as that is where YOU think the problem exists.

Im not trying to give everyone a hard time, but I just need to know how to remove what seems to be interference in the system.

Did you try my simple stepper code? Does the problem also arise with that?

Debugging is usually best accomplished by simplification.

...R

Yes, that is my setup. The schematic from Polulu was modified by me, to make it match my setup, as the one from Polulu was the one resembling the setup the most. I also made one in Fritzing, but unless im missing out something, there are alot of parts missing in Fritzing.

Again I want to apologize if I was interpreted angry, im not, but I found it confusing as why the schematic was called for, as it was attached to the very first post. You reasoning that it was looking like the Polulu schematic explains the fuzz. :slight_smile:

The first program works, runs one time, as Loop() is empty and setup is only run.

Second doesnt work as it required buttons, This cannot be tested by me as i dont have any buttons available and it would require that I disassemble the machine.

It still skips steps occationally once in a while just as my original code, so im kinda positive it aint the code. but something physical needed to be done. Im a novice in this field, and I dont want to fry anything :slight_smile:

Yes, I had assumed it was the Pololu Schematic. When I look closely at your version (in your Original Post) I don't see any connection between logic GND and your micro-controller. That is the sort of thing that is less likely to be overlooked in a pencil drawing of the schematic (IMHO).

And I have another problem with your picture. It gives no sense of the physical wiring arrangement that YOU have and which YOU seem to think might be the cause of the problem. For example, you mention long wires but there is no indication in the image of which ones they are.

I have some of these motors and they seem to work perfectly with their long un-shielded wires connected to Pololu A4988 drivers and with the Uno connected to my PC with 3 metres of USB cable.

...R