Step counting and problems with Int

Below is my program. Under cutting() and backStep() the stepper motors are supposed to go 1 step forwards or backwards until i hit a button, and the stepper returns to the starting position, which are saved as “long stepCount;” I kept it simple by saying when i hit the button to stop, go in the opposite direction the same amount of steps that were taken. This is a step counter for a stock edge finder for my mill.

This works great until i reach the int limit of 32,767 of steps taken, and then instead of going in the opposite direction, it goes the same direction, but steps less than did at first. Originally i had it set as “int long stepCount” and then removed the int to see if it made a difference, but it didn’t so i’m here. with it listed as long value, i thought it would count up to 2+ million steps if wanted, but it doesn’t. I even tried a couple variations but didn’t have any luck

can someone please tell why it’s doing this? it was by accident i even found this problem. I was counting steps on a stopwatch so i could chart the speed/steps/time ratio and then ran into this issue.

thanks

#include <Stepper.h>

                    
Stepper stepper1(6400, 4, 3);
Stepper stepper2(3200, 12, 11);

                  
   
   const int dirPin  = 3;      // stepper1 direction pin 
   const int stepPin = 4;      // stepper1 step pin
   const int enPin = 5;        // stepper1 enable pin
   const int enPin2 =13;         // stepper2 enable pin
   
   int home_Switch = 10;          // homing switch
   const byte back_Switch = 7;     // backStep switch
   const byte cutting_Switch = 8;   // cutting switch
   const byte front_Switch = 9;    // frontStep switch
   
   byte switch1State;              // cutting switch state
   byte switch2State;             // frontStep switch state
   byte switch3State;            // homeSwitch state
   byte switch4State;           // backStep state

   byte lastSwitch2State=HIGH;
   byte lastSwitch4State=HIGH;
      
   int long toothStep;    // steps to next tooth 
   int stepSpeed;
 
   long stepCount; 

   
   

void setup() {
 
  Serial.begin(115200);
  
  pinMode(enPin, OUTPUT);                // stepper1 enable output
  pinMode(enPin2, OUTPUT);               // stepper2 enable output
  pinMode( home_Switch, INPUT_PULLUP);   // home switch mode
  pinMode( cutting_Switch, INPUT_PULLUP);     // cutting switch mode
  pinMode( front_Switch, INPUT_PULLUP);     // frontStep switch mode
  pinMode( back_Switch, INPUT_PULLUP);  // backStep switch mode
  digitalWrite(enPin, HIGH);             // stepper1 enable = high
  digitalWrite(enPin2, HIGH);            // stepper2 enable = high

      Serial.println(" ");
      Serial.println(" Press Forward To Begin");
      Serial.println(" ");
 
  while (digitalRead(front_Switch)){  }

      Serial.println(" Started Homing");
      Serial.println(" ");

   while (digitalRead(home_Switch)) {     //CCW rotation
                                          // homing code
       stepper1.step(1);
       delayMicroseconds(2000);
          
    }
    
  Serial.println(" You are at home");      //letting me know you are at home
  delay(1000);        // delay after homing before able to push any buttons

       
       Serial.println(" ");
       Serial.print(" How many steps is the tooth?");
     while (Serial.available()==0) {   }
      toothStep = Serial.parseInt();
      while (Serial.available() != 0 ) {Serial.read();}
      Serial.print("     #");
      Serial.print(toothStep);
      Serial.println(" ");
     
       
       Serial.println(" ");
       Serial.print(" How fast are you going? Fast 1-10 or Slow: 10-200");
     while (Serial.available()==0) {   }
       stepSpeed = Serial.parseInt();
     while (Serial.available() != 0 ) {Serial.read();}
       Serial.print("     #");
       Serial.print(stepSpeed);
       Serial.println(" ");
       
       




      


          
}
   


void loop() {
  
  checkButtons();              // read buttons status
  cutting();                   // cutting profile
  frontStep();                 // step tooth forward
  backStep();                  // step tooth backward
  speedButton();
  
 
}

void checkButtons() {
  
  switch1State = digitalRead(cutting_Switch);   // reading stepUp button
  switch2State = digitalRead(front_Switch);  // reading frontStep button
  switch3State = digitalRead(home_Switch);  //reading home_switch button
  switch4State = digitalRead(back_Switch);  //reading backStep button
}

void cutting() {       //CW rotation step counter

      
      if (switch1State == LOW){              // if cutting_Switch activated

          
   while (digitalRead(home_Switch)){ 
         
       
         stepper1.step(1);
         stepCount++;
         Serial.println(stepCount);
         delay(stepSpeed);
   }
         Serial.println(" ");
         Serial.print("Steps: ");
         Serial.println(stepCount);
         Serial.println(" ");
         
         stepper1.setSpeed(50);
         stepper1.step(-stepCount);
         delay(500);
         stepCount=0;
   }
 }



void frontStep(){   // center of next tooth profile

  if (switch2State == LOW){                           // if front_Switch button activated
     
    stepper1.setSpeed(50);
    stepper1.step(toothStep);
    
       stepCount=0;

       }
        
 }




void backStep(){         //CCW rotation step counting

   if (switch4State==LOW)  {     // if back_Switch button activated

 while (digitalRead(home_Switch)){

        stepper1.step(-1);
        stepCount--;
        Serial.println(stepCount);
        delay(stepSpeed);
         

      }
    
    Serial.println(" ");
    Serial.print("backSteps: ");
    Serial.println(stepCount);
    Serial.println(" ");
    
        stepper1.setSpeed(50);
        stepper1.step(-stepCount);
        delay(500);
        stepCount=0;
    } 
          
} 

void speedButton(){

  if (switch3State==LOW && switch4State==LOW){
       
       Serial.println(" ");
       Serial.print(" Manual Speed Change;  1-200");
    while (Serial.available()==0) {   }
       stepSpeed = Serial.parseInt();
    while (Serial.available() != 0 ) {Serial.read();}
       Serial.print("      #");
       Serial.print(stepSpeed);
       Serial.println(" ");

   }
}

You have some pretty good debug output printed to Serial in your code. What does it say when the problem starts to occur?

An int has a maximum positive value of 32767 and if you add one more it becomes -32768.

An unsigned int can go up to 65535.

If you do need higher negative numbers use a long rather than an int.

...R

@OP

Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2);

But the Stepper.h Library demands that the number_of_steps should be a +ve number not greater than 32767.

GolamMostafa:
@OP

But the Stepper.h Library demands that the number_of_steps should be a +ve number not greater than 32767.

Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2);

number_of_steps in that case is the number of steps for one full rotation of the stepper motor, and would necessarily always have to be positive.

The pertinent function for this discussion is:

void step(int number_of_steps);

where number_of_steps is "the number of steps to turn the motor - positive to turn one direction, negative to turn the other (int)" , which is also limited to a signed integer.

If the number of steps exceeds the limits of an integer, you will have to handle that in your program.

Since the long addition to the code didn’t fix the problem. I’m probably limited by the stepper.h library itself, which was always a concern i had when i started doing this. So i’ll just look into doing the same movements and serial readout using the accelstepper library instead.

the serial readout doesn’t give any indication what’s wrong. from that point of view, everything works normally, and i’m not limited by the counting the number of steps. it only messes up when i go more than 32767 steps and try to return to it’s starting point. And then it steps 32767 forward, but i don’t have any debugging code for that movement.

It would be fairly easy to modify the code, if you really want to use the stepper.h library, although there would be a (probably imperceptible) delay in the stepping sequence every 32767 steps.

Just change the code from:

stepper1.setSpeed(50);
stepper1.step(-stepCount);
delay(500);
stepCount=0;

to something like this, to allow for the limits of an integer:

stepper1.setSpeed(50);
while (abs(stepCount) > 32767) {
  if (stepCount > 0) {
    stepper1.step(-32767);  //stepCount positive
    stepCount = stepCount - 32767;
  } else {
    stepper1.step(32767);  //stepCount negative
    stepCount = stepCount + 32767;
  }
}
stepper1.step(-stepCount);
delay(500);
stepCount = 0;

That worked really well. but it created a question. that bit of code did away with the integer limit, completely. and i'm not exactly sure how it did it because after reading the code, it halfway makes since. but i just let it step 250,000 and it went right back to where it was.

i can understand it subtracting or adding 32767 to make up for going over a little. But what causes it to keep count of steps that are 10x the 32767 limit when it's time to go back? i guess i'm just trying to understand the code better.

thanks

Here is the code with comments to explain it a bit better:

stepper1.setSpeed(50);

while (abs(stepCount) > 32767) { //repeatedly execute the follow code while the absolute value of stepCounter is greater than 32767

  if (stepCount > 0) { //execute this code if stepCount is a positive number
    stepper1.step(-32767);  //drive the stepper motor back toward 0 by -32767 steps
    stepCount = stepCount - 32767;  // substract 32767 from stepCount

  } else {  //execute this code if stepCount is a negative number
    stepper1.step(32767);  //drive the stepper motor back toward 0 by 32767 steps 
    stepCount = stepCount + 32767;  //add 32767 to stepcount 
  }
}

// this code gets executed when the absolute value of stepCount is less than or equal to 32767
stepper1.step(-stepCount);  //drive the stepper motor back to 0
delay(500); // this is from your original code, not sure what its purpose is
stepCount = 0;  //set stepCount to 0 because stepper motor is now at 0

Basically, if stepCount is larger than the integer limit of 32767, it sends a command to move the stepper motor by 32767 steps, then reduces the value of stepCount by the corresponding amount of 32767. This gets repeated as many times as necessary to reduce stepCount to a value equal to or less than 32767.

(abs(stepCount) > 32767) is comparing the absolute value of stepCount to 32767, so that it works for either negative or positive values of stepCount.

i guess what confused me was i'm not familiar with the abs command and what it does. Well i know what it is, but i haven't needed to use it until now.