ESP8266 + TB6600 + Nema 17

Hi,
I am trying to control my stepper with nodemcu ESP8266. The hardware config:

  • ENA+ to D8
  • PUL+ to D5
  • DIR+ to D2
  • ENA-, PUL-, DIR- to GND

V1 (switch button) function is meant to set the direction CW or CCW. V2 (push button) function is meant to run the motor (10 steps). However, the stepper motor now (Nema 17) is only vibrating and not running. It does nothing when I press the button on Blynk App. Can anyone suggest me a solution? Thank you.

Here is the code.


#include <Stepper.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

const char* ssid     = "xxxx";
const char* pass = "yyyy";
char auth[] = "zzzz";

WiFiServer server(80);

const int PUL = 14;  // D5  
const int DIR = 4;  // D2
const int ENA = 15;  // D8 

void setup() {
  Serial.begin(9600);
  // put your setup code here, to run once:
  Blynk.begin(auth, ssid, pass);
  WiFi.begin(ssid, pass);
  
  pinMode(PUL, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(ENA, OUTPUT);
  digitalWrite(ENA, HIGH);
  server.begin();
}

BLYNK_WRITE(V1){
  int pinValue = param.asInt();
  if (pinValue == 1) {
    digitalWrite(DIR, HIGH);
  }
  else {
    digitalWrite(DIR, LOW);
  }
}

BLYNK_WRITE(V2){
  int pinValue = param.asInt();
  if (pinValue == 1) {
    for (int x=0; x < 10; x++)
    {
      digitalWrite(PUL, HIGH);
      delay(15);
      digitalWrite(PUL, LOW);
      delay(15);
    }
  }
}

void loop(){
  Blynk.run();
}


This has NOTHING to do with Blynk.

A ESP, or most any microcontroller, can NOT handle the needed currents to directly drive a stepper motor from digital pins. If you havenā€™t already killed your ESP, you will.

You need to use a motor controller and separate power. Google how to control stepper motors.

TB6600 is a stepper motor driver ā€¦ :wink:

I am using separate 12V, 2A power supply for my TB6600 and connected the board with the PC.

@IBK You are correct :blush: ā€¦ I hate when people rely on the title for supplying technical details and info, and/or donā€™t include all relevant details in the initial post anyhow :stuck_out_tongue:

@cpcp07 You include the stepper.h library, but I donā€™t see any actual stepper motor commands in your code.

Steppers rely on constant pulses to get from A to B. Unless this controller has full autonomous control over all that, then you need to provide it in precisely timed code.

I recommend you Google how to use that controller without Blynk first to learn how to make it work.

Be aware, Blynkā€™s IoT timing and a steppers required timing can often conflict. To work around that I have used dual controllers, one running Blynk that send commands to another running the stepper code.

OK, this device still seems to require the MCU to handle the control pulsesā€¦ so you may be running into my aforementioned timing issues.

Actually, I am not trying to use the stepper.h library. Some of the code on google using TB6600 is not using the library. Only manual pinMode.

http://forum.arduino.cc/index.php?action=dlattach;topic=232993.0;attach=77158

Then remove itā€¦ we look at your code, not read your mind :stuck_out_tongue:

Also, above linked demo code runs in the main loop (that runs thousands of times a second - and not a good idea to try that while using Blynk) and also uses delayMicroseconds(), not delay() in-between pulses. Soā€¦ Yup, timing issues.

@cpcp07: Apart from the 'delay()` causing timing issues Iā€™d strongly suggest to remove more unnecessary code from your test program. That is:

...
//#include <Stepper.h>
...
//WiFiServer server(80);
...
//WiFi.begin(ssid, pass);
...
//server.begin();
...

Apart form Blynk:

  • Is the TB6600 set-up correct regarding ā€œMicro Stepā€ and ā€œCurrent Limitā€ settings and +/- connection of the motor?
  • Does the motor turn with a simple test code like this: ?
#define PUL 14;  // D5  
#define DIR 4;   // D2
#define ENA 15;  // D8 

void setup(){
 pinMode(PUL, OUTPUT);
 pinMode(DIR, OUTPUT);
 pinMode(ENA, OUTPUT);
 digitalWrite(PUL, LOW);
 digitalWrite(DIR, LOW);
 digitalWrite(ENA, HIGH);
}

void loop(){
 digitalWrite(PUL, !digitalRead(PUL));
 delayMicroseconds(50);
}

It is correct. The motor turn with the code and a tweak as follows:


digitalWrite(ENA, LOW);

or if I didnā€™t change the code (digitalWrite(ENA, HIGH) and I removed the pin connection from nodemcu board D8 to TB6600. The motor turns. Can anyone explain why I have to change it to LOW? And does this mean that my initial code should be working if I change the delay to delayMicroseconds?
Thank you.

I tried it with the following code and it is still not working.

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

const char* ssid     = "xxxx";
const char* pass = "yyyy";
char auth[] = "zzzz";

const int PUL = 14;  // D5 14 
const int DIR = 4;  // D2 4
const int ENA = 15;  // D8 15 

void setup() {
  Serial.begin(9600);
  // put your setup code here, to run once:
  Blynk.begin(auth, ssid, pass);
  pinMode(PUL, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(ENA, OUTPUT);
  digitalWrite(ENA, LOW);
}

BLYNK_WRITE(V1){
  int pinValue = param.asInt();
  if (pinValue == 1) {
    digitalWrite(DIR, HIGH);
  }
  else {
    digitalWrite(DIR, LOW);
  }
}

BLYNK_WRITE(V2){
  int pinValue = param.asInt();
  if (pinValue == 1) {
    for (int x=0; x < 10; x++)
    {
      digitalWrite(PUL, HIGH);
      delayMicroseconds(50);
      digitalWrite(PUL, LOW);
      delayMicroseconds(50);
    }
  }
}
BLYNK_WRITE(V3){
  int pinValue = param.asInt();
  if (pinValue == 1){
    digitalWrite(ENA, HIGH);
  }
  else {
    digitalWrite(ENA, LOW);
    }
}

void loop(){
  Blynk.run();
}

@cpcp07: Reading the TB6600 manual results to the following: :wink:

[ā€¦]
"5. Off-line Function (EN Terminal):
If you turn on the Off-line function, the motor will enter a free state. You can adjust
the motor shaft freely, and the pulse signal will be no response. If you turn it off, it will be
back into automatic control mode.
Note: Generally, EN terminal is not connected."
[ā€¦]

Hello! i had the same problem and i solved it and implement acceleration with this code:


#include <AccelStepper.h>
 
long receivedMMdistance = 0; //distance in mm from the computer
long receivedDelay = 0; //delay between two steps, received from the computer
long receivedAcceleration = 0; //acceleration value from computer
char receivedCommand; //character for commands
/* s = Start (CCW) // needs steps and speed values
 * c = close (CW) //needs steps and speed values
 * a = set acceleration // needs acceleration value
 * n = stop right now! // just the 'n' is needed
 */
 
bool newData, runallowed = false; // booleans for new data from serial, and runallowed flag
 
// direction Digital 9 (CCW), pulses Digital 8 (CLK)
AccelStepper stepper(1, D2, D5);
// connect enable+ to arduino D8
int ENA = D8;

void setup()
{
  Serial.begin(115200); //define baud rate
  Serial.println("Testing Accelstepper"); //print a message
  pinMode(ENA, OUTPUT);
  //setting up some default values for maximum speed and maximum acceleration
  stepper.setMaxSpeed(2000); //SPEED = Steps / second
  stepper.setAcceleration(1000); //ACCELERATION = Steps /(second)^2
 
  stepper.disableOutputs(); //disable outputs, so the motor is not getting warm (no current)
}
 
void loop()
{
  checkSerial(); //check serial port for new commands
  continuousRun2(); //method to handle the motor
}
 
void continuousRun2() //method for the motor
{
  if (runallowed == true)
  {
    if (abs(stepper.currentPosition()) < receivedMMdistance) //abs() is needed because of the '<'
    {
      stepper.enableOutputs(); //enable pins
      stepper.run(); //step the motor (this will step the motor by 1 step at each loop)
    }
    else //program enters this part if the required distance is completed
    {
      runallowed = false; //disable running -> the program will not try to enter this if-else anymore
      stepper.disableOutputs(); // disable power
      Serial.print("POS: ");
      Serial.println(stepper.currentPosition()); // print pos -> this will show you the latest relative number of steps
      stepper.setCurrentPosition(0); //reset the position to zero
      Serial.print("POS: ");
      Serial.println(stepper.currentPosition()); // print pos -> this will show you the latest relative number of steps; we check here if it is zero for real
    }
  }
  else //program enters this part if the runallowed is FALSE, we do not do anything
  {
    return;
  }
}
 
void checkSerial() //method for receiving the commands
{  
  //switch-case would also work, and maybe more elegant
 
  if (Serial.available() > 0) //if something comes
  {
    receivedCommand = Serial.read(); // this will read the command character
    newData = true; //this creates a flag
  }
 
  if (newData == true) //if we received something (see above)
  {
    //START - MEASURE
    if (receivedCommand == 's') //this is the measure part
    {
      //example s 2000 500 - 2000 steps (5 revolution with 400 step/rev microstepping) and 500 steps/s speed
      runallowed = true; // allow running
      receivedMMdistance = Serial.parseFloat(); //value for the steps
      receivedDelay = Serial.parseFloat(); //value for the speed
      Serial.print(receivedMMdistance); //print the values for checking
      Serial.print(receivedDelay);
      Serial.println("Measure "); //print the action
      stepper.setMaxSpeed(receivedDelay); //set speed
      stepper.move(receivedMMdistance); //set distance
    }

    // START - CLOSE

    if (receivedCommand == 'c') //CLOSING - Rotates the motor in the opposite direction as opening
    {
      //example c 2000 500 - 2000 steps (5 revolution with 400 step/rev microstepping) and 500 steps/s speed; will rotate in the other direction
      runallowed = true; //allow running
      receivedMMdistance = Serial.parseFloat(); //value for the steps
      receivedDelay = Serial.parseFloat(); //value for the speed
      Serial.print(receivedMMdistance);  //print the values for checking
      Serial.print(receivedDelay);
      Serial.println("CLOSE "); //print action
      stepper.setMaxSpeed(receivedDelay); //set speed
      stepper.move(-1 * receivedMMdistance); ////set distance - negative value flips the direction
    }

    //STOP - STOP

    if (receivedCommand == 'n') //immediately stops the motor
    {
      runallowed = false; //disable running
      stepper.setCurrentPosition(0); // reset position
      Serial.println("STOP "); //print action
      stepper.stop(); //stop motor
      stepper.disableOutputs(); //disable power
    }

 //SET ACCELERATION

    if (receivedCommand == 'a') //Setting up a new acceleration value
    {
      runallowed = false; //we still keep running disabled, since we just update a variable
      receivedAcceleration = Serial.parseFloat(); //receive the acceleration from serial
      stepper.setAcceleration(receivedAcceleration); //update the value of the variable
      Serial.print("Acceleration: "); //confirm update by message
      Serial.println(receivedAcceleration); //confirm update by message
    }
  }
  //after we went through the above tasks, newData becomes false again, so we are ready to receive new commands again.
  newData = false;
}

You should include AccelStepper library and pins are:
DIRECTION = D2
PULSE = D5
ENABLE = D8

Please edit your post to add triple backticks at the beginning and end of your code so that it displays correctly.
Triple backticks look like this:
```

Pete.

Sorryā€¦