Stepper direction by using "attachInterrupt"

Firstly, sorry for activating old post.

My question is how to change direction after every 5000 steps by using Timer1 and Stepper library.

PS. I am using Timer1 because I want to make super-precise angle measurement.

There is a simple situation:

    Timer1.initialize();
    Timer1.attachInterrupt(tick, 1000000.0f / (2000 * 1));

...

void tick()
{
    horStepper.step(1);
 
    stepCounth++;
    
    if(stepCounth >= 5000)
    {
        stepCounth = 0;
        roundCount++;
    }
}

As this is a VERY old Thread I am suggesting to the Moderator to move your question to its own Thread.

I don't understand the logic of this

I am using Timer1 because I want to make super-precise angle measurement.

The angle moved by a stepper motor is determined by the number of steps, not by the timing of the steps.

If you describe your project it will be much easier to give useful advice.

How many steps per second do you need?

...R
Stepper Motor Basics
Simple Stepper Code

@mrsrdjani

TOPIC SPLIT
DO NOT HIJACK / NECRO POST !

Could you take a few moments to Learn How To Use The Forum.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Sorry for beginner’s mistakes.

I am making small lidar scanner and I plan to move stepper motor to 360 degrees clockwise and 360 degrees counterclockwise, without delay by using interrupt.

The number of steps per seconds are irrelevant for me.

#include <TimerOne.h>
#include <Wire.h>
#include <Stepper.h>
#include <LIDARLite.h>







Stepper horStepper(1000,2,3);
Stepper verStepper(1000,4,5);
 
 
volatile int stepCounth = 0;
volatile int stepCountv = 0;

volatile int roundCount = 0;

 
float anglev = 0;
 
void setup() {
    Serial.begin(115200);
    
 
    Timer1.initialize();
    Timer1.attachInterrupt(tick, 1000000.0f / (2000 * 1));
}
 
void loop() {
    receive(true);
 
    for(int i = 0; i < 99; i++)
        receive(false);
}
 
void receive(bool bias)
{
    float angleh = ((float)stepCounth / 5000.0f) * 360.0f;  
    float anglev = ((float)stepCountv / 5000.0f) * 360.0f; 

    Serial.print(angleh);
    Serial.print(",");
    Serial.print(180 - anglev);
    Serial.print(",");
    Serial.print("LIDAR");
    Serial.print("\n");

   

 
    if(roundCount >= 2)
    {
        verStepper.step(1);
        stepCountv++;
 
        if(anglev >= 10)
            anglev = 0;
            
        roundCount = 0;
    }
 
}
 
void tick()
{
    horStepper.step(1);
 
    stepCounth++;
    
    if(stepCounth >= 5000)
    {
        stepCounth = 0;
        roundCount++;
    }
}

How do you change direction using the stepper library? I would expect that to be a really common function. Have you looked?

Simply with:

horStepper.step(-1);

But I don't understand how implement it with interrupt.

mrsrdjani:
Simply with:

horStepper.step(-1);

But I don’t understand how implement it with interrupt.

It’s no different in or out of an interrupt. You will need a variable to remember and set the direction at the appropriate time (which you have to define). What I would do, is Stepper.step(amount) and then set amount = 1 or amount = -1 depending on which direction you want to go.

Can you show me a simple example? I’m freaked out.

So, when I run this code it makes just one direction change.

int amount = 1;

...

void tick()
{
    horStepper.step(amount);
    stepCounth++;

    if(stepCounth >= 5000)
    {
        stepCounth = 0;
        roundCount++;
        amount = -1;

    }
   
}

mrsrdjani:
I am making small lidar scanner and I plan to move stepper motor to 360 degrees clockwise and 360 degrees counterclockwise, without delay by using interrupt.

The number of steps per seconds are irrelevant for me.

The code in the second example in the link I gave you in Reply #1 Simple Stepper Code should be able to do that perfectly well without the complexity of a hardwareTimer or interrupts.

...R

Robin2:
The code in the second example in the link I gave you in Reply #1 Simple Stepper Code should be able to do that perfectly well without the complexity of a hardwareTimer or interrupts.

…R

Thank you Robin, I know for your code, and it works same thing like my interrupt. Problem is how to make loop for alternating change direction when it cross n steps.

This code does just one direction change:

void loop() {

    curMillis = millis();

       if (curMillis < 1000) {
        digitalWrite(directionPin, HIGH);
        singleStep();
        curMillis++;
      }

      if (curMillis >= 1000) {
        stepCounth = 0;
        digitalWrite(directionPin, LOW);
        singleStep();
        curMillis = 0;
      }
}

Try this. Look carefully at all the changes I have made from your version.

void loop() {

    curMillis = millis();
    static char direction = 'F';
        // the word static causes the value to be remembered between calls to the function
    static unsigned long stepCount = 0;
    unsigned long maxSteps = 400; // change to what ever value you need
    unsigned long millisBetweenSteps = 100; // 10 steps per second
    static unsigned long lastStepMillis;
    
    if (direction == 'F') {
        digitalWrite(directionPin, HIGH);
    }
    else {
        digitalWrite(directionPin, LOW);
    }

    if (curMillis - lastStepMillis < millisBetweenSteps) {
        lastStepMillis = curMillis;
        singleStep();
        stepCount ++;
    }
    
    if (stepCount >= maxSteps) {
        if (direction == 'F') {
            direction = 'R';
        }
        else {
            direction = 'F';
        }
        stepCount = 0;
    }

}

…R

Dear, Robin, thank you!

Your code works like as I excepted. That solved my problem.
I never found any similar code and my question is why does static make sense?

Finally,

I wrote successfully code for interrupt with Robin’s code.

#include <TimerOne.h>
#include <Wire.h>
#include <Stepper.h>
#include <LIDARLite.h>







Stepper horStepper(1000,2,3);
Stepper verStepper(1000,4,5);
 
 
volatile int stepCounth = 0;
volatile int stepCountv = 0;

volatile int roundCount = 0;

int amount = 1;
 
float anglev = 0;
 
void setup() {
    Serial.begin(115200);
    pinMode(7, OUTPUT);
 
    Timer1.initialize();
    Timer1.attachInterrupt(tick, 1000000.0f / (2000 * 1));
}
 
void loop() {
    receive(true);
 
    for(int i = 0; i < 99; i++)
        receive(false);
}
 
void receive(bool bias)
{
    float angleh = ((float)stepCounth / 5000.0f) * 360.0f;  
    float anglev = ((float)stepCountv / 5000.0f) * 360.0f; 

    Serial.print(angleh);
    Serial.print(",");
    Serial.print(180 - anglev);
    Serial.print(",");
    Serial.print("LIDAR");
    Serial.print("\n");

   

 
    if(roundCount >= 2)
    {
        verStepper.step(1);
        stepCountv++;
 
        if(anglev >= 10)
            anglev = 0;
            
        roundCount = 0;
    }
 
}
 
void tick() {
    static char direction = 'F';

{
    if (direction == 'F') {
        horStepper.step(amount);
        stepCounth++;
    }
    else {
        horStepper.step(-amount);
        stepCounth++;
    }
    

    if(stepCounth >= 5000)
    {
        stepCounth = 0;
        if (direction == 'F') {
            direction = 'R';
        }
        else {
            direction = 'F';
        }
        stepCounth = 0;
        roundCount++;
    }
   
}
}

mrsrdjani:
I never found any similar code and my question is why does static make sense?

In C++ variables are either defined globally (those at the top of the program before setup() ) or locally (those defined within a function). Global variables are available everywhere throughout a program but local variables are only available within the function where they are defined. Normally local variables are created afresh every time the function is called so they cannot remember the value from the previous time the function was called. Using the static keyword tells the compiler that you want the values in the local variable to be retained between calls to the function.

...R

I don't think you grasped my concept. What I meant was like:

void tick() {
  static int direction = amount;
  horStepper.step(direction);
  stepCounth++;
  if (stepCounth >= 5000)
  {
    stepCounth = 0;
    direction = -direction;
    roundCount++;
  }
}

Interesting

aarg:
I don't think you grasped my concept. What I meant was like:

I think your code is doing much the same as mine but mine is more long winded - I was hoping to illustrate the logical steps.

...R

Robin2:
I think your code is doing much the same as mine but mine is more long winded - I was hoping to illustrate the logical steps.

…R

Ah, I see… I thought this was OP’s code. My bad.

Thank you guys, everything is clear now.

The final code is:

void tick() {
  
  static int direction = amount;
  horStepper.step(direction);
  stepCounth++;
  if (stepCounth >= 40000 || stepCounth == 0)
  {
    stepCounth--;
    stepCounth = (-stepCounth);
    direction = -direction;
    roundCount++;
  }
}