Stepper control - Need help

I want to control a stepper motor based on the input pulses. The pulses will come from a source to pin 2. Each pulse will be counted. A timer1 interrupt will interrupt after 100milli seconds and check the count. If less than 31 the stepper will move in a direction. If more than 35, then in another direction. if it is between 31 and 35 then stepper should be idle.

I have played a lot to my knowledge and now I am stuck and need help with this. My code is messed up due to experimenting but I am posting it anyway. I hope someone can make sense of it and guide me what I am doing wrong.

/*
 *  Timer1 library example
 *  June 2008 | jesse dot tane at gmail dot com
 */
 
#include "TimerOne.h"
 
 
 
 
 
 
 
int motorPin1 = 8;
int motorPin2 = 9;
int motorPin3 = 10;
int motorPin4 = 11;
int delayTime = 50; //this is delay between each step of the stepper motor i.e. motor speed

//int pin = 13; //declared LED for output (blink)
//volatile int state = RISING; //Trigger on rising edge

//int pin7 = 7;


int Hertz = 0; //Global integer


int Astep = 0; //Global integer which will be used as a flag to keep track of stepper movement
int Bstep = 0;
int Cstep = 0;
int Dstep = 0;

 
 
 
void setup()
{
  pinMode(13, OUTPUT); //timer test blink
  Timer1.initialize(100000);         // initialize timer1, and set a 1/2 second period
           
  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt
  
  
  
  pinMode(motorPin1, OUTPUT);  // pins set for output
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  
  //pinMode(pin, OUTPUT);
  attachInterrupt(0, count, RISING);
  
  
  
}
 

void loop()
{
    
  //digitalWrite(pin, state); //for blinking
  
  //delay (300); //setting delay so that after 200mili seconds number of pulses is counted
  
   //Hertz = counter();
  
 // check(Hertz); //function for counting pulses and taking a decision
  

}
 
 
 

void  count() //responsible for blinking of LED and calling counter
{
  //state = !state;
  counter(); //increment the count of hertz
  
  
}

int counter() //pulses added here after the delay thus after 300 milli secounds, the count will be compared
{
  Hertz++;
  return (Hertz); //glbal integer returned
  
}


void callback()
{
  digitalWrite(13, digitalRead(13) ^ 1);
  
  Hertz= counter();
  
  check(Hertz);
}
 

void check(int Hertz){
  
  if (Hertz < 31 && Hertz >5 )
  {
    low();
  }
    else if (Hertz > 35)
      {
        high();
        
      }
      
      if (Hertz <=5){
       sustain();
      }
      
}

int low()

{
  if (Astep == 0) {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
  Astep = 1;
  Dstep = 0;
 }
  
  else if (Bstep == 0 && Astep ==1)
  {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
   Bstep = 1;
 }
  
  else if (Cstep == 0 && Bstep ==1)
  {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
 Cstep =1;
    }
  
 else if (Dstep == 0 && Astep ==1)
  {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
 Dstep=1;
  Cstep=0;
   Bstep=0;
    Astep=0;
  }
  
  return (Astep, Bstep, Cstep, Dstep);
}


int high()
{
  
  
   if (Astep == 0) {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
  Astep = 1;
  Dstep = 0;
  }
  
  else if (Bstep == 0 && Astep ==1)
  {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
  Bstep = 1;
  }
  
  else if (Cstep == 0 && Bstep ==1)
    {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
  Cstep =1;
    }
  
  else if (Dstep == 0 && Astep ==1)
  {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
 Dstep=1;
  Cstep=0;
   Bstep=0;
    Astep=0;
  }
  
  
return (Astep, Bstep, Cstep, Dstep);
}

    
   

void sustain()
{
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
}

I hope someone can make sense of it and guide me what I am doing wrong.

First, you posted your code incorrectly. Modify your post. Select the code, and press the icon with the # on it. Save the post. That puts the code in a box that is scrollable.

Second, you described what the program should do, but not what it does do. So, we can only assume that you need help finding a needle in a haystack. I'm not fond of search for pointy things. At least you need to provide a clue as to where in the haystack you dropped the needle.

Sorry for that. This is my first time posting in a forum.

With the above code, the stepper just goes counter clock wise. There is no response to the interrupt on pin 2.

There is some logical error but I have failed to find it out.

So I want to know a) Does my code work for interrupt on pin 2, i.e. increment the variable HERTZ? Is pin 2 (based on my code) capable of receiving pulses (should count high pulse).
b) Is my concept of timer interrupt correct that after 100milli it checks the hertz count?
c) Is the logic of Hertz comparison correct?
d) Is stepper movement codded good enough?

So basically, I need help with someone checking the code step by step. I am working on it as I post so don't assume I am couch potato. Thanks.

From what I can see you do everything inside the interrupt service routine. This is bad. One reason is that it stops so many other things from running including other interrupts. An interrupt routine can't be interrupted.

An ISR should be as short as possible, just counting and setting flags. You should then use the flags in the main foreground routine to initiate actions, like stepping the motors.

  Timer1.initialize(100000);         // initialize timer1, and set a 1/2 second period

How does 100000 map to 1/2 a second?

How is the stepper motor connected to the Arduino? Not directly, I hope.

There is a Stepper library. Why are you not using it?

void  count() //responsible for blinking of LED and calling counter
{
  //state = !state;
  counter(); //increment the count of hertz
  
  
}

int counter() //pulses added here after the delay thus after 300 milli secounds, the count will be compared
{
  Hertz++;
  return (Hertz); //glbal integer returned
  
}

Why does the ISR do nothing but call another function? Why does counter() return a value that count() ignores? Either it doesn't need to return a value, or count() should not be ignoring it.

Values used in ISRs that are also used elsewhere need to be declared volatile.

return (Astep, Bstep, Cstep, Dstep);

What? You can't return more than one value from a function. These variables are all globals, anyway.

You need to go through your code, and decide if variables are to be local or global. If they are global, they should not be passed to or returned by a function. If they are to be passed to or returned by a function, they should not be global.

Does my code work for interrupt on pin 2, i.e. increment the variable HERTZ? Is pin 2 (based on my code) capable of receiving pulses (should count high pulse).

Only you can tell that, unless you want to send one of us the hardware.

What is providing the pulses on pin 2? Are you certain that pin 2 is being pulsed? How long are the pulses HIGH?

This code works for my stepper. I think you are trying to do too many things at once. Get the program working on something simple and then add complexity.

int orange = 8;
int blue = 9;
int pink = 11;
int yellow = 10;
int millisecs = 50;

void setup()
{
pinMode (orange, OUTPUT);
pinMode (blue, OUTPUT);
pinMode (pink, OUTPUT);
pinMode (yellow, OUTPUT);
Serial.begin(9600);
Serial.println("Start");

}

void loop()

{
//delay (5000);

for (int i=0; i <= 200; i++)
{

// step 1
delay(millisecs);
digitalWrite(orange, LOW);
digitalWrite(yellow, LOW);
digitalWrite(pink, LOW);
digitalWrite(blue, HIGH);

// step 2
delay(millisecs);
digitalWrite(orange, LOW);
digitalWrite(yellow, LOW);
digitalWrite(pink, HIGH);
digitalWrite(blue, HIGH);

// step 3

delay(millisecs);
digitalWrite(orange, LOW);
digitalWrite(yellow, LOW);
digitalWrite(pink, HIGH);
digitalWrite(blue, LOW);

// step 4
delay(millisecs);
digitalWrite(orange, LOW);
digitalWrite(yellow, HIGH);
digitalWrite(pink, HIGH);
digitalWrite(blue, LOW);

// step 5
delay(millisecs);
digitalWrite(orange, LOW);
digitalWrite(yellow, HIGH);
digitalWrite(pink, LOW);
digitalWrite(blue, LOW);

// step 6
delay(millisecs);
digitalWrite(orange, HIGH);
digitalWrite(yellow, HIGH);
digitalWrite(pink, LOW);
digitalWrite(blue, LOW);

// step 7
delay(millisecs);
digitalWrite(orange, HIGH);
digitalWrite(yellow, LOW);
digitalWrite(pink, LOW);
digitalWrite(blue, LOW);

// step 8
delay(millisecs);
digitalWrite(orange, HIGH);
digitalWrite(yellow, LOW);
digitalWrite(pink, LOW);
digitalWrite(blue, HIGH);

Serial.println(i);
}
}

Ok,with following code I am able to count the pulses and when pulses go above 31 the direction of stepper changes. The pulses come on pin 2 interrupt. I am also able to set a 0.3second timer which blinks an LED.

I need advise on how to count 31 pulses in 0.3 seconds then reset the Hertz so that counter starts from zero. if 31 pulses, motor in one direction if more than 31 pulses in 0.3 seconds motor should go in another direction.

Also I tried setting a state between 31 - 35 pulses where the motor should be idle. Below and above that action should be taken. But I couldn't do it as the arduino seemed to freeze or the program just ended. I commented that function named sustain(). Please give suggestion for that as well.

#include "TimerOne.h"
int motorPin1 = 8;
int motorPin2 = 9;
int motorPin3 = 10;
int motorPin4 = 11;
int delayTime = 50; //this is delay between each step of the stepper motor i.e. motor speed


int Astep = 0; //Global integer which will be used as a flag to keep track of stepper movement
int Bstep = 0;
int Cstep = 0;
int Dstep = 0;



int Hertz = 0; // Global Variable. This will be incremented each time the loop runs






int pin = 13; //for interrupt HW Pulse
volatile int state = LOW;//for interrupt HW Pulse


void setup()
{ 
  
  
  pinMode(motorPin1, OUTPUT);  // pins set for output
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);

  
   pinMode(pin, OUTPUT);//for interrupt HW Pulse
  attachInterrupt(0, blink, RISING);//for interrupt HW Pulse
  
  
  
   //Sets up PWM output on pin 5 with a 50% duty cycle, and attaches an interrupt that toggles digital pin 6 every .3 second.
  //for timmer interrupt
  pinMode(6, OUTPUT);
  Timer1.initialize(300000);         // initialize timer1, and set a .3 second period
  Timer1.pwm(5, 512);                // setup pwm on pin 5, 50% duty cycle
  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt
}
  


void loop()
{


  
check(); //Decision for stepper movement. It is based on value of a
  
  
digitalWrite(pin, state);//for interrupt HW Pulse
  
  

}

  //for timmer interrupt
void callback()
{
  digitalWrite(6, digitalRead(6) ^ 1);
  
 
}
 

void blink()//for interrupt HW Pulse, this is called externally via H/W
{
  state = !state;
  increment();

}


int increment()

{
 Hertz++;

  return (Hertz);
}




void check(){

  if (Hertz <= 31  )
  {
    low();
   return;
  }
  

    else if (Hertz > 31)
      {
        high();
        return;
      }
      
     /* else if (Hertz <=35 && Hertz >= 31){
       sustain();
       return;
      }
      */
}







int low()

{
//  if (Astep == 0) {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
//  Astep = 1;
//  Dstep = 0;
  
  //Condition ...
  
 // int u=1;
//  return (u);
// }
  
//  else if (Bstep == 0 && Astep ==1)
//  {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
//   Bstep = 1;
// }
  
 // else if (Cstep == 0 && Bstep ==1)
 // {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
 //Cstep =1;
 //   }
  
 //else if (Dstep == 0 && Astep ==1)
 // {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
 //Dstep=1;
 // Cstep=0;
  // Bstep=0;
  //  Astep=0;
  //}
  
  //return (Astep, Bstep, Cstep, Dstep);
}


int high()
{
  
  
   //if (Astep == 0) {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
//  Astep = 1;
 // Dstep = 0;
//  }
  
//  else if (Bstep == 0 && Astep ==1)
//  {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
//  Bstep = 1;
//  }
  
 // else if (Cstep == 0 && Bstep ==1)
//    {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
//  Cstep =1;
 //   }
  
//  else if (Dstep == 0 && Astep ==1)
//  {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
// Dstep=1;
 // Cstep=0;
//   Bstep=0;
 //   Astep=0;
 // }
  
  
//return (Astep, Bstep, Cstep, Dstep);
}

    
   

/*void sustain()
{
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);

}*/
void loop()
{


  
check(); //Decision for stepper movement. It is based on value of a
  
  
digitalWrite(pin, state);//for interrupt HW Pulse
  
  

}

What's with all the white space? The comments mean what?

int Hertz = 0; // Global Variable. This will be incremented each time the loop runs

So, why isn't it volatile?

increment() still returns a global variable. The return value is still not used.

PaulS:

Thank you for the reply. Strangely enough it was working. Nevertheless, your advise has taken and appreciated.

Apologies for the bad formatting. I am constantly editing the code and experimenting so it has all these white lines. I am cleaning it up.

Any suggestions about timer interrupt counting the hertz and then resetting it for another count?

#include "TimerOne.h" //Timer Interrupt header file
int motorPin1 = 8; //Steppet motor pin setup
int motorPin2 = 9; //Steppet motor pin setup
int motorPin3 = 10; //Steppet motor pin setup
int motorPin4 = 11; //Steppet motor pin setup
int delayTime = 50; //this is delay between each step of the stepper motor i.e. motor speed


int Astep = 0; //Global integer which will be used as a flag to keep track of stepper movement. Currently not being used.
int Bstep = 0;
int Cstep = 0;
int Dstep = 0;

volatile int Hertz = 0; // Global Variable. This will be incremented each time the loop runs



int pin = 13; //For interrupt HW Pulse. 
volatile int state = LOW;//For interrupt HW Pulse


void setup()
{ 
  
  
  pinMode(motorPin1, OUTPUT);  // Stepper Pins set for output
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);

  
  pinMode(pin, OUTPUT);//for interrupt HW Pulse
  attachInterrupt(0, blink, RISING);//for interrupt HW Pulse
  
  
  
   //Sets up PWM output on pin 5 with a 50% duty cycle, and attaches an interrupt that toggles digital pin 6 every .3 second.
  //for timmer interrupt
  pinMode(6, OUTPUT);
  Timer1.initialize(300000);         // initialize timer1, and set a .3 second period
  Timer1.pwm(5, 512);                // setup pwm on pin 5, 50% duty cycle
  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt
}
  


void loop()
{
  
check(); //Decision for stepper movement.
  
  
digitalWrite(pin, state);//for interrupt HW Pulse
}


//for timmer interrupt

void callback()
{
  digitalWrite(6, digitalRead(6) ^ 1); 
}
 

void blink()//for interrupt HW Pulse, this is called externally via H/W
{
  state = !state;
  increment();
}


int increment()

{
 Hertz++;

  return (Hertz);
}




void check()
{

  if (Hertz <= 31  )
    {
      low();
      return;
    }
  
  if (Hertz <=35 && Hertz > 31)
      {
       sustain();
       
      }

     if (Hertz > 35)
      {
        high();
        return;
      }
}



int low()

{
//  if (Astep == 0) {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
//  Astep = 1;
//  Dstep = 0;
  
  //Condition ...
  
 // int u=1;
//  return (u);
// }
  
//  else if (Bstep == 0 && Astep ==1)
//  {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
//   Bstep = 1;
// }
  
 // else if (Cstep == 0 && Bstep ==1)
 // {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
 //Cstep =1;
 //   }
  
 //else if (Dstep == 0 && Astep ==1)
 // {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
 //Dstep=1;
 // Cstep=0;
  // Bstep=0;
  //  Astep=0;
  //}
  
  //return (Astep, Bstep, Cstep, Dstep);
}


int high()
{
  
  
   //if (Astep == 0) {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
//  Astep = 1;
 // Dstep = 0;
//  }
  
//  else if (Bstep == 0 && Astep ==1)
//  {
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
//  Bstep = 1;
//  }
  
 // else if (Cstep == 0 && Bstep ==1)
//    {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, HIGH);
  delay(delayTime);
//  Cstep =1;
 //   }
  
//  else if (Dstep == 0 && Astep ==1)
//  {
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, LOW);
  delay(delayTime);
  
// Dstep=1;
 // Cstep=0;
//   Bstep=0;
 //   Astep=0;
 // }
  
//return (Astep, Bstep, Cstep, Dstep);
}
    
   

void sustain()
{
  digitalWrite(motorPin1, HIGH);
  digitalWrite(motorPin2, HIGH);
  digitalWrite(motorPin3, HIGH);
  digitalWrite(motorPin4, HIGH);
  return;
}

Any suggestions about timer interrupt counting the hertz and then resetting it for another count?

The variable Hertz is already counting. The callback() function should simply divide the value by the tine between calls to the function. Then, set the value of Hertz back to 0.