[SOLVED] 28BYJ-48 is not going to rotate counterclockwise and other issues

I have brought 28BYJ-48 motors and driver boards based on ULN2003A for my CNC device.

Driver board Stepper motor

![
500x396](http://i.imgsafe.org/2c27a3e7a9.jpg)
Manufacturer: HEX (China). Manufacturer is not specified

My sketch

Using serial port communication to change things.

When I type
[/u] [u]go[/u] [u]
motor does full revolution clockwise.

After all,
[/u] [u]dir[/u] [u]
changes further direction to counterclockwise.

Now
[/u] [u]go[/u] [u]
moves clockwise, but also penetrating counterclockwise a little bunch of steps, and then moving clockwise, and many-many times again. ::slight_smile: Showing some resistance, it looks like it can summon the demon. :smiling_imp:

As the result, motor doesn't move to right destination when AccelStepper library outputs signals in reverted order (for CCW movement).

Issues:

  • What prevents CCW movement of motor and how to fix it?
  • Why half-step mode just makes motor vibrating and doing nothing?

Issues are now solved, thanks to MarkT!

Sketch's code:

/*
  Unknown Nonblocking CNC
  Author: VINTproYKT
*/

#include <AccelStepper.h>
#include <MultiStepper.h>

// The most preferred maximum speed for my motors, experimentally calculated by checking for penetration of motor shaft
#define MOTORS_MAXSPEED 360
// Acceleration must be as minimal as to keep motor avoiding penetration of the shaft
#define MOTORS_ACCELERATION 100
#define MOTORS_STEPS_PER_REVOLUTION 2048

/* Motor subject: 28BYJ-48 - 5V
Connect it to PCB driver based on ULN2003A.
Connect driver's:
  + VCC to Arduino's Vin
  + GND to GND
  + IN1 to D2 (digital pin 2)
  + IN2 to D3
  + IN3 to D4
  + IN4 to D5
Then use external 5V power supply.*/
AccelStepper motorX(AccelStepper::FULL4WIRE, 2, 3, 4, 5);
// Can't run it on half-step mode, so trying the best on full

short motorX_dir = 1;// [ CCW : -1 ] <=> [ 1 : CW ]
int motorX_avgSpeed = MOTORS_MAXSPEED;// Average speed for every motion

String input = "";

void doCommand(String command, String param) {// Serial commands hub
  if (command == "go") {
    long steps = param.toInt();
    if (steps == 0) steps = MOTORS_STEPS_PER_REVOLUTION;// Make full revolution by default
    _go(steps);
  }
  else if (command == "stop") _stop();
  else if (command == "dir") _dir();
  else if (command == "speed") {
    float speed = param.toInt();
    if (speed == 0) speed = MOTORS_MAXSPEED;// Average speed equals maximum speed by default
    _speed(speed);
  }
}

void setup() {
  Serial.begin(115200);// Maximum baud rate for Arduino UNO
  Serial.println("setup");
  
  input.reserve(128);
  
  motorX.setMaxSpeed(MOTORS_MAXSPEED);
  motorX.setAcceleration(MOTORS_ACCELERATION);
}

void loop() {
  while (Serial.available()) {
    input = Serial.readStringUntil('\n');
    input.trim();
    int input_sp = input.indexOf(' ');// Checking for space character in input string
    String input_command = input;
    String input_param;
    if (input_sp > 0) {
      input_command = input.substring(0, input_sp);
      input_param = input.substring(input_sp + 1);
      input_param.trim();
    }
    doCommand(input_command, input_param);
    input = "";
  }
  
  measureSteps();
  
  motorX.run();
}

void _go(long increment) {
  if (motorX.speed() == 0) {
    motorX.setSpeed(motorX_avgSpeed);
    motorX.moveTo(motorX.currentPosition() + motorX_dir * increment);
    Serial.print("Move to ");
    Serial.print(motorX.targetPosition());
    Serial.print(" (rotate by ");
    Serial.print((float)increment / (float)MOTORS_STEPS_PER_REVOLUTION * 360);
    Serial.print("° ");
    if (motorX_dir > 0) Serial.print("clockwise");
    else Serial.print("counterclockwise");
    Serial.println(")");
  }
}

void _stop() {
  motorX.stop();
  motorX.setSpeed(0);
  Serial.println("Stop");
}

void _dir() {
  motorX_dir = -motorX_dir;
  if (motorX_dir > 0) Serial.println("CW");
  else Serial.println("CCW");
}

void _speed(float speed) {
  motorX_avgSpeed = speed;
  Serial.print("Average speed changed to ");
  Serial.println(speed);
}

void measureSteps() {
  if (motorX.speed() != 0) {
    Serial.print("Position: ");
    Serial.print(motorX.currentPosition());
    Serial.print(" | Speed: ");
    Serial.println(motorX.speed());
  }
}

You assume the order of wires is the same order they need to be sequenced in, that's probably not the case.

There are 24 ways to order 4 wires, and only 8 or those will work. Try swapping wires (with power off)
and trying again. Repeat till success!

MarkT:
You assume the order of wires is the same order they need to be sequenced in, that's probably not the case.

There are 24 ways to order 4 wires, and only 8 or those will work. Try swapping wires (with power off)
and trying again. Repeat till success!

Thank you! I have just wrapped IN2 and IN3 and whole deal is working as expected now (in both directions)!
Very big thanks, MarkT!

Updated sketch for working in half-step mode.

P.S.: Chinese manufacturer of driver boards, HEX, put big headache on me! Now I'm not surprised why they don't ever have website on the net. It's just typical small and untrusted manufacturer.

1 Like