stepper drive code

Hello

I'm working on project with stepper drive and variable speed. Stepper drive use pulses for speed adjustment. High pulse is always 1ms and I want to adjust low pulse time with encoder. It worked with delay function but it was not responsive. Now I have tried with this code and I don't get any pulse?
Can someone please help with code?

Kind regards

const int inputCLK = 12;             // pin encoder CW
const int inputDT = 13;              // pin encoder CCW
 
const int stepperpulse = 5;             // pin stepper 
 
 int counter = 100;                   // initialize counter 
 int currentStateCLK;     
 int previousStateCLK;
 const long interval = 1000;           // high pulse interval 
  
  
 String encdir ="";
 
 void setup() { 
   
   pinMode (inputCLK,INPUT);        // set encoder pin as input
   pinMode (inputDT,INPUT);         // set encoder pin as input
   pinMode (stepperpulse,OUTPUT);   // set stepper pin as outputs
   Serial.begin (9600);             // setup serial monitor 
   
   previousStateCLK = digitalRead(inputCLK); // read the initial state of CLK
       
 } 
 
 void loop() { 
  
   currentStateCLK = digitalRead(inputCLK);      // Read the current state of inputCLK
   unsigned long currentMillis = millis();
   unsigned long previousMillis; 
    
   if (currentStateCLK != previousStateCLK){ 
     if (digitalRead(inputDT) != currentStateCLK) {      // If the inputDT state is different than the inputCLK state then encoder is rotating counterclockwise
       counter --;
       encdir ="CCW";
        
     } else {                                           // Encoder is rotating clockwise
       counter ++;
       encdir ="CW";
         }
     Serial.print("--Direction: ");
     Serial.print(encdir);
     Serial.print(" -- Value: ");
     Serial.println(counter);
     Serial.print(" -- previousMillis: ");
     Serial.print(previousMillis);
     Serial.print(" -- currentMillis: ");
     Serial.print(currentMillis);
     } 
     previousStateCLK = currentStateCLK;               // Update previousStateCLK with the current state
   
     { 
     if (currentMillis - previousMillis >= interval)
        digitalWrite(stepperpulse,HIGH);
       
    
       else {
      if (currentMillis - previousMillis >= 500) {
        digitalWrite(stepperpulse,LOW);
        previousMillis = currentMillis;
          }
     }
    }
   }

Have a look at the second (non-blocking) example in this Simple Stepper Code Use your encoder to change the value of millisBetweenSteps.

One millisec seems long for a stepper driver pulse. 10 microsecs is usually enough.

...R

Robin2:
Have a look at the second (non-blocking) example in this Simple Stepper Code Use your encoder to change the value of millisBetweenSteps.

One millisec seems long for a stepper driver pulse. 10 microsecs is usually enough.

...R

Thank you for fast reply, but I have seen your post allready and I can't get it to work. Even your code (with changed IO's) doesn't work. Tried it and it does nothing. Scope shows nothing. I'm using Adafruit Huzzah board. Can that be problem?

Loco_roko:
Tried it and it does nothing. Scope shows nothing.

Post the program (based on my code) that YOU uploaded.

What stepper driver are you using? Can it work with the 3.3v signals from an ESP8266?

...R

Hello,

Thank you very much for your help and sorry for the late responce.
Stepperdrive is JBL and it's now in use with labview crio (that's why my pulse time is 1ms, didn't have time to put it in FPGA mode and run it in RT). Drive is still not connected with huzzah. Drive can't work with 3.3V pin but I have breadboard for adafruit with pull down circuit on it for encoder, transistors and 5V supply. So it will use 5V. Problem that I have is even with your code (changed IO numbers by me) i don't get any pulse out of it. Scope is connected to pin 5 (step pin) and my signal stays low.

What I do see is if i turn my encoder with your code my onboard led (pin 15) is going on and off and in aother direction it stays on untill turned off.

Kind regards

// testing a stepper motor with a Pololu A4988 driver board or equivalent

// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push switches
// press one and it turns CW, press the other and it turns CCW

byte directionPin = 2;
byte stepPin = 5;

byte buttonCWpin = 12;
byte buttonCCWpin = 13;

boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;

byte ledPin = 15;

unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 25; // milliseconds

void setup() {

     Serial.begin(9600);
     Serial.println("Starting Stepper Demo with millis()");

     pinMode(directionPin, OUTPUT);
     pinMode(stepPin, OUTPUT);
     pinMode(ledPin, OUTPUT);
     
     pinMode(buttonCWpin, INPUT_PULLUP);
     pinMode(buttonCCWpin, INPUT_PULLUP);
     
}

void loop() {
   
    curMillis = millis();
    readButtons();
    actOnButtons();
   
}

void readButtons() {
   
    buttonCCWpressed = false;
    buttonCWpressed = false;
   
    if (digitalRead(buttonCWpin) == LOW) {
        buttonCWpressed = true;
    }
    if (digitalRead(buttonCCWpin) == LOW) {
        buttonCCWpressed = true;
    }
}

void actOnButtons() {
    if (buttonCWpressed == true) {
        digitalWrite(directionPin, LOW);
        singleStep();
    }
    if (buttonCCWpressed == true) {
        digitalWrite(directionPin, HIGH);
        singleStep();
    }
}

void singleStep() {
    if (curMillis - prevStepMillis >= millisBetweenSteps) {
            // next 2 lines changed 28 Nov 2018
        //prevStepMillis += millisBetweenSteps;
        prevStepMillis = curMillis;
        digitalWrite(stepPin, HIGH);
        digitalWrite(stepPin, LOW);
    }
}

Loco_roko:
Problem that I have is even with your code (changed IO numbers by me) i don't get any pulse out of it. Scope is connected to pin 5 (step pin) and my signal stays low.

The program is very simple so I don't see why it would not work but, sorry, I don't know anything about the ESP8266 board that you are using.

Do you have an Uno or Mega that you could try the program on?

...R

Can you add some lines printing to the Serial monitor to which part of the code is being executed when you turn the encoder ?

Deva_Rishi:
Can you add some lines printing to the Serial monitor to which part of the code is being executed when you turn the encoder ?

My understanding is that the OP cannot even get the motor to move with a simple program and no encoder.

...R

Scope is connected to pin 5 (step pin) and my signal stays low.

If you disconnect the Feather Huzzah from the board it is driving, can you verify the pin going HIGH and LOW with simple digitalWrite() test commands?

The esp8266 supports less current output than an AT328. Is is possible that what the pin is connected to is pulling the output down?

Paired digitalWrite() commands are usually slow enough on an AT328 to provide a sufficiently long drive signal to the stepper driver. On the esp8266 it will be considerably faster given the processor speed and the different register code underlying digitalWrite(). You may need a few microsecond delay between commands.

So I have done few tests, just back from store with Arduino uno. Arduino uno works fine, runs every code without problem, code from Robin2, reads encoder, interrupt....

So problem seems to be with HUZZAH board, D1 mini....

cattledog:
If you disconnect the Feather Huzzah from the board it is driving, can you verify the pin going HIGH and LOW with simple digitalWrite() test commands?

The esp8266 supports less current output than an AT328. Is is possible that what the pin is connected to is pulling the output down?

Paired digitalWrite() commands are usually slow enough on an AT328 to provide a sufficiently long drive signal to the stepper driver. On the esp8266 it will be considerably faster given the processor speed and the different register code underlying digitalWrite(). You may need a few microsecond delay between commands.

Pin's work when simple "delay ()" used. They go on, off, blinking...
I'm starting to think there is something wrong with my IDE?

Pin's work when simple "delay ()" used. They go on, off, blinking...

so the output is working, can you do a simple input check with just a resistor or resistor to GND on the input pin

byte buttonCWpin = 12;
byte buttonCCWpin = 13;

byte ledPin = 15;

void setup() {

     pinMode(ledPin, OUTPUT);
     
     pinMode(buttonCWpin, INPUT_PULLUP);
     pinMode(buttonCCWpin, INPUT_PULLUP);
     
}
void loop() {
  if (digitalRead(buttonCWpin)==LOW) digitalWrite(ledPin, HIGH);
  else digitalWrite(ledPin, LOW);
}

and with changing the pinMode to INPUT, and using a hardware pull-up resistor instead ?

So problem seems to be with HUZZAH board, D1 mini....

A FeatherHuzzah is not a Lolin D1 mini. What board are you selecting when you compile?

Deva_Rishi:
so the output is working, can you do a simple input check with just a resistor or resistor to GND on the input pin

byte buttonCWpin = 12;

byte buttonCCWpin = 13;

byte ledPin = 15;

void setup() {

pinMode(ledPin, OUTPUT);
   
    pinMode(buttonCWpin, INPUT_PULLUP);
    pinMode(buttonCCWpin, INPUT_PULLUP);
   
}
void loop() {
  if (digitalRead(buttonCWpin)==LOW) digitalWrite(ledPin, HIGH);
  else digitalWrite(ledPin, LOW);
}


and with changing the pinMode to INPUT, and using a hardware pull-up resistor instead ?

Inputs are working with your code but they where working with encoder. I had to use hardware pull-up because without it inputs don't work. Tried all example codes from arduino website / forums and the only one code that works with encoder on boards except (uno) is this one:

void loop() {
 
   currentStateCLK = digitalRead(inputCLK);      // Read the current state of inputCLK
   unsigned long currentMillis = millis();
   unsigned long previousMillis;
   
   if (currentStateCLK != previousStateCLK){
     if (digitalRead(inputDT) != currentStateCLK) {      // If the inputDT state is different than the inputCLK state then encoder is rotating counterclockwise
       counter --;
       encdir ="CCW";
       
     } else {                                           // Encoder is rotating clockwise
       counter ++;
       encdir ="CW";
         }
     Serial.print("--Direction: ");
     Serial.print(encdir);
     Serial.print(" -- Value: ");
     Serial.println(counter);
     Serial.print(" -- previousMillis: ");
     Serial.print(previousMillis);
     Serial.print(" -- currentMillis: ");
     Serial.print(currentMillis);
     }
     previousStateCLK = currentStateCLK;               // Update previousStateCLK with the current state
   
     {
     if (currentMillis - previousMillis >= interval)
        digitalWrite(stepperpulse,HIGH);
       
   
       else {
      if (currentMillis - previousMillis >= 500) {
        digitalWrite(stepperpulse,LOW);
        previousMillis = currentMillis;
}

every other example doesn't work while with uno everything works.

cattledog:
A FeatherHuzzah is not a Lolin D1 mini. What board are you selecting when you compile?

The one I use, I have Huzzah, Wemos D1 mini, Uno and Zero pro here. Only one working in UNO.
Librarys for huzzah, wemos and zero pro are installed.

Loco_roko:
Pin's work when simple "delay ()" used. They go on, off, blinking...

The pulses in my Simple Stepper Code are very short. Do the settings on your 'scope allow for that?

Also, you will probably need an explicit pulse width on an ESP8266 because a pair of back-to-back digitalWrite()s will operate much faster than on an Uno.

...R

Inputs are working with your code but they where working with encoder. I had to use hardware pull-up because without it inputs don't work.

Great, this was somehow not clear to me hence the question.

Also, you will probably need an explicit pulse width on an ESP8266 because a pair of back-to-back digitalWrite()s will operate much faster than on an Uno.

in other words, try like this :

void singleStep() {
    if (curMillis - prevStepMillis >= millisBetweenSteps) {
            // next 2 lines changed 28 Nov 2018
        //prevStepMillis += millisBetweenSteps;
        prevStepMillis = curMillis;
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(stepPin, LOW);
    }
}

Robin2:
The pulses in my Simple Stepper Code are very short. Do the settings on your 'scope allow for that?

Also, you will probably need an explicit pulse width on an ESP8266 because a pair of back-to-back digitalWrite()s will operate much faster than on an Uno.

...R

Yes scope is Tektronix 200MHz / 5 GS/s, settings are ok, created pulse with labview and it detects them.

Deva_Rishi:
Great, this was somehow not clear to me hence the question.in other words, try like this :

void singleStep() {

if (curMillis - prevStepMillis >= millisBetweenSteps) {
            // next 2 lines changed 28 Nov 2018
        //prevStepMillis += millisBetweenSteps;
        prevStepMillis = curMillis;
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(stepPin, LOW);
    }
}

Doesn't work.

Is there difference in code betwen UNO / ESP?

Loco_roko:
Is there difference in code betwen UNO / ESP?

I don’t know the answer but it seems to me it is time for you to write a very short program that does nothing but produce a 10µsec pulse every 200 millisecs and see if it works on the Uno and on the ESP8266.

…R

Shouldn't that code:

void singleStep() {
    if (curMillis - prevStepMillis >= millisBetweenSteps) {
            // next 2 lines changed 28 Nov 2018
        //prevStepMillis += millisBetweenSteps;
        prevStepMillis = curMillis;
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(stepPin, LOW);
    }
}

be

void singleStep() {
    static unsigned long prevStepMillis = 0 ;
    unsigned long curMillis = millis() ;
    if (curMillis - prevStepMillis >= millisBetweenSteps) {
        prevStepMillis += millisBetweenSteps;
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(stepPin, LOW);
    }
}

MarkT:
Shouldn't that code:

be

It is part of a larger program so the static local variable is not essential.

And I prefer to use the simpler

prevStepMillis = curMillis;

unless the minor errors that it may give rise to are a deal breaker.

...R

If the pulses are produced the same way, then maybe the difference in logic-HIGH level is to blame (though usually 3.3v is enough) can you try putting a non-inverting TTL-chip in between (or 2 inverting ones )