Stepper moves the wrong way

Hi.

I got a problem whit a stepper starts to move in the wrong way.

Setup:
Stepper nema 17
Easy Motor
Keypad
Mega 2560

If i print "500 mm" and press enter, the stepper goes anticlockwise
"600 mm" same
"700 mm" same
"800 mm" same
"900 mm" same

But if i enter 930 or more the stepper goes clockwise??

I need the range to be from 500mm to 1500mm anticlockwise and 1500mm to 500mm clockwise.
or vise versa.

I have try to change the "calculatedmove" but i dont understan why the stepper switch direction?

Anyone have an ide of whats wrong?

Thanks.

#include <AccelStepper.h> // AccelStepper Library
#include <Keypad.h>  // Keypad Library
#include "U8glib.h"  // U8glib for Nokia LCD

// Variables to hold entered number on Keypad
volatile int firstnumber=99;  // used to tell how many numbers were entered on keypad
volatile int secondnumber=99;
volatile int thirdnumber=99;
volatile int fourthnumber=99;

// Variables to hold Distance and CurrentPosition
int keyfullnumber=0;  // used to store the final calculated distance value
String currentposition = "";  // Used for display on Nokia LCD


// Keypad Setup
const byte ROWS = 4; // Four Rows
const byte COLS = 4; // Four Columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {22, 24, 26, 28}; // Arduino pins connected to the row pins of the keypad
byte colPins[COLS] = {31, 33, 35, 37}; // Arduino pins connected to the column pins of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );  // Keypad Library definition


// U8glib Setup for Nokia LCD
#define backlight_pin 11
U8GLIB_PCD8544 u8g(3, 4, 6, 5, 7);  // Arduino pins connected to Nokia pins:
                                    // CLK=3, DIN=4, CE=6, DC=5, RST=7
                                   
                                   
// AccelStepper Setup
AccelStepper stepper(1, A0, A1);  // 1 = Easy Driver interface
                                  // Arduino A0 connected to STEP pin of Easy Driver
                                  // Arduino A1 connected to DIR pin of Easy Driver
                                 
// parte pin reset carrello



void setup(void) {
 
  //  Light up the LCD backlight LEDS
  analogWrite(backlight_pin, 100);  // Set the Backlight intensity (0=Bright, 255=Dim)
   
  //  AccelStepper speed and acceleration setup
  stepper.setMaxSpeed(1500);  // Not to fast or you will have missed steps
  stepper.setAcceleration(400);  //  Same here
 
// parte while reset carrello


  

 // Draw starting screen on Nokia LCD
  u8g.firstPage();
  do {
  u8g.drawHLine(0, 15, 84);
  u8g.drawVLine(50, 16, 38);
  u8g.drawHLine(0, 35, 84);
  u8g.setFont(u8g_font_profont11);
  u8g.drawStr(0, 10, "ENTER DISTANCE");
  u8g.drawStr(62, 29, "MM");
  u8g.drawStr(4, 46, "cur-pos");
  }
  while( u8g.nextPage() );
 
}


void loop(){
 
  char keypressed = keypad.getKey();  // Get value of keypad button if pressed
  if (keypressed != NO_KEY){  // If keypad button pressed check which key it was
    switch (keypressed) {
     
      case '1':
        checknumber(1);
      break;
       
      case '2':
        checknumber(2);
      break;

      case '3':
        checknumber(3);
      break;

      case '4':
        checknumber(4);
      break;

      case '5':
        checknumber(5);
      break;

      case '6':
        checknumber(6);
      break;

      case '7':
        checknumber(7);
      break;

      case '8':
        checknumber(8);
      break;

      case '9':
        checknumber(9);
      break;

      case '0':
        checknumber(0);
      break;

      case '*':
        deletenumber();
      break;

      case '#':
        calculatedistance();
      break;
    }
  }

}

void checknumber(int x){
  if (firstnumber == 99) { // Check if this is the first number entered
    firstnumber=x;
    String displayvalue = String(firstnumber);  //  Transform int to a string for display
    drawnokiascreen(displayvalue); // Redraw Nokia lcd
   
  } else {
    if (secondnumber == 99) {  // Check if it's the second number entered
      secondnumber=x;
      String displayvalue = (String(firstnumber) + String(secondnumber));
      drawnokiascreen(displayvalue);
  } else {
    if (thirdnumber == 99) {  // Check if it's the 3rd number entered
      thirdnumber=x;
      String displayvalue = (String(firstnumber) + String(secondnumber) + String(thirdnumber));
      drawnokiascreen(displayvalue);

    } else {  // It must be the 3rd number entered
      fourthnumber=x;
      String displayvalue = (String(firstnumber) + String(secondnumber) + String(thirdnumber) + String(fourthnumber));
      drawnokiascreen(displayvalue);

      }
    }
  }
}

 
void deletenumber() {  // Used to backspace entered numbers
    if (fourthnumber !=99) {
      String displayvalue = (String(firstnumber) + String(secondnumber) + String(fourthnumber));
      drawnokiascreen(displayvalue);

    fourthnumber=99;
  }
  else { 
   if (thirdnumber !=99) {
      String displayvalue = (String(firstnumber) + String(secondnumber));
      drawnokiascreen(displayvalue);

    thirdnumber=99;
  }
  else {
    if (secondnumber !=99) {
      String displayvalue = String(firstnumber);
      drawnokiascreen(displayvalue);

      secondnumber=99;
   }
   else {
     if (firstnumber !=99) {
       String displayvalue = "";
       drawnokiascreen(displayvalue);

       firstnumber=99;
        }
      }
    }
  }
}
 
void calculatedistance() {  // Used to create a full number from entered numbers

    if (fourthnumber == 99 && thirdnumber == 99 && secondnumber == 99 && firstnumber != 99) {
      keyfullnumber=firstnumber;
      movestepper(keyfullnumber);
    }
   
    if (secondnumber != 99 && thirdnumber == 99 && fourthnumber == 99) {
      keyfullnumber=(firstnumber*10)+secondnumber;
      movestepper(keyfullnumber);
    }
   
    if (thirdnumber != 99 && fourthnumber == 99) {
      keyfullnumber=(firstnumber*100)+(secondnumber*10)+thirdnumber;
      movestepper(keyfullnumber);
    }
       
    if (fourthnumber != 99) {
      keyfullnumber=(firstnumber*1000)+(secondnumber*100)+(thirdnumber*10)+fourthnumber;
      movestepper(keyfullnumber);
    }
   
    resetnumbers(); // Reset numbers to get ready for new entry
  }


void movestepper(int z) {  //  Move the stepper

  long calculatedmove=(z*2100)/20;  //  Calculate number of steps needed in mm
  stepper.runToNewPosition(calculatedmove);
  currentposition = String(z);
  u8g.firstPage();
  do {
    u8g.drawHLine(0, 15, 84);
    u8g.drawVLine(50, 16, 38);
    u8g.drawHLine(0, 35, 84);
    u8g.setFont(u8g_font_profont11);
    u8g.drawStr(0, 10, "ENTER DISTANCE");
    u8g.drawStr(62, 29, "MM");
    u8g.drawStr(4, 46, "cur-pos");
    u8g.setPrintPos(57,47);
    u8g.print(currentposition);       
  }
  while( u8g.nextPage() );
}
               
void resetnumbers() {  // Reset numbers for next entry
  firstnumber=99;
  secondnumber=99;
  thirdnumber=99;
  fourthnumber=99;
}
 

void drawnokiascreen(String y) {

    u8g.firstPage();
    do {
      u8g.drawHLine(0, 15, 84);
      u8g.drawVLine(50, 16, 38);
      u8g.drawHLine(0, 35, 84);
      u8g.setFont(u8g_font_profont11);
      u8g.drawStr(0, 10, "ENTER DISTANCE");
      u8g.setPrintPos(0,29);
      u8g.print(y);  // Put entered number on Nokia lcd   
      u8g.drawStr(62, 29, "MM");
      u8g.drawStr(4, 46, "cur-pos");
      u8g.setPrintPos(57,47);
      u8g.print(currentposition);  //  Display current position of stepper
    }
      while( u8g.nextPage() );

}

I suspect it is this line

long calculatedmove=(z*2100)/20;

it may be trying to calculate the value as an int and causing the value to overflow

To verify this add some print statement to print z and calculatedmove.

Try

long calculatedmove=(z*2100UL)/20;

In any case. you can simplify the calculation to z * 105;

...R

If Robin's fix makes it always go the wrong way
( and I suspect it will ), reverse one coils two leads.
( assuming 4 wire ).
Dwight

Robin2:
I suspect it is this line

long calculatedmove=(z*2100)/20;

it may be trying to calculate the value as an int and causing the value to overflow

To verify this add some print statement to print z and calculatedmove.

Try

long calculatedmove=(z*2100UL)/20;

In any case. you can simplify the calculation to z * 105;

...R

Thanks Robin2, it works now:)

But i still having problem whit the messuremt, i use a ball screw, if i set from 600mm to 700mm it works, but if i go from 600mm to 1400mm the messuremt is of by 30mm.

Its there somthing missing in the code when i use a ball screw?

What is the pitch of you ball screw and is it short or long?
Dwight

the pitch is 2mm and its 500mm long in total.

the messure on the maskin i will put this ball screw on is alittle diffrent and i need to adjust so it will work.

On the maskin the messuremen is like this: 100mm is in real life only 50mm.

So when i have the ball screw att lets say 600mm and i need it to got to 650mm, i will put in 700mm on the lcd.

This works now but not long distance.

If i change the value so it works from 600 to 1400, then it will not work from 600 to 700mm and vise versa

I asked the questions poorly.
What is the length of the screw?
What way is it off, short or long?
How many steps does your stepper motor have per revolution.
Does the problem repeat after 1400 to 2100mm ?
Dwight

The screw length is 500mm
Its off on the long way
1.8 degree (easy driver) 200 step per revolution

I cant go that far, but i think it will

Thanks for helping

How do you go 1400mm if the screw is only 500mm long?

If the pitch is 2mm and you have 200 steps per revolution,
one mm takes 100 steps.
1400mm takes 140000 steps.
Dwight

thats becaurse i use the messurment that the maskin use, start is at 600mm, then i print in 1400mm (100mm on the maskin is extuly 50mm, so from 600mm to 1400mm its 400mm in real.

Sorry for my bad eng, hard to explaine:(

Trigger80:
thats becaurse i use the messurment that the maskin use, start is at 600mm, then i print in 1400mm (100mm on the maskin is extuly 50mm, so from 600mm to 1400mm its 400mm in real.

Sorry for my bad eng, hard to explaine:(

????
What's a maskin?
Dwight

:slight_smile: sorry... i meen the machine...

the machine is build in this way, to add more space,

machine= 600mm
mm ruler= 600mm

machine=700mm
mm ruler=650

machine=1000mm
mm ruler=800

machine=1400mm
mm ruler= 1000mm

and so on.

Ok offset and scale.
Dwight

I still don't understand the problem.

If the screw is 500mm how can the stepper motor make anything move beyond that?

The stepper motor will be limited by the physical properties of the machine. If you can change the range of some scale on the machine that won't make any difference to the physical properties.

If you want to be able to command the motor to move to the points indicated on the scale you may have to change the relationship between steps and mm

...R

If you move the motor 200 steps (1 REV), how far does the maskin move?

Robin2:
I still don't understand the problem.

If the screw is 500mm how can the stepper motor make anything move beyond that?

The stepper motor will be limited by the physical properties of the machine. If you can change the range of some scale on the machine that won't make any difference to the physical properties.

If you want to be able to command the motor to move to the points indicated on the scale you may have to change the relationship between steps and mm

...R

The stepper motor dosent go beyond that, the stepper goes from 600mm "start" of the screw then i goes
to 1000mm, thats 400mm and then i have 100mm left.

Machine scale: "start" 600mm----------700mm----------800mm----------900mm----------1000mm----------
MM Ruler "start" 600mm-----700mm-----800mm-----900mm-----1000mm-----1100mm-----1200mm

Where "-"is 1cm.

I got the stepper to be +/- 4mm if i go from 600mm to 1400mm, its mutch better then before.
If i play around whit smal distance move it work realy good.

outsider:
If you move the motor 200 steps (1 REV), how far does the maskin move?

i realy dont move the machine, i move a holder that holds senors on the machine, but it will move 1mm.

I got this scale thing worked out, the problem is that long distance makes the messuremt off be 4mm.
Short distance works fine.

Trigger80:
The stepper motor dosent go beyond that, the stepper goes from 600mm "start" of the screw then i goes
to 1000mm, thats 400mm and then i have 100mm left.

I am tempted to say I understand that but experience has taught me not to be so rash. Can you explain it in more detail?

And your scale and ruler in Reply #16 may be meanginless after HTML has had its way. This is a case where you need to make a drawing and post a photo of it.

Have you added any Serial.print() statements into your program so that you can monitor the actual numbers it is using.

Your Reply #17 just adds to my confusion, I'm afraid.

...R

I understand, its hard to exlaine,

I will draw somthing up to make it more clear.