Stepper Motor Cant Seem to Work

Hello everyone, I would like to ask for your help if you dont mind please.

So I am trying to control the speed of a stepper motor while also showing the rpm in an lcd. However, the stepper motor wont seem run. Can anyone help me find what's wrong with my code? I am new to arduino, so I dont really know the problem. Thank You Very Much.

The code is as shown below.

float REV = 0;
int RPM_VALUE;
int PREVIOUS = 0;
int TIME;
#include <AccelStepper.h>
#include <LiquidCrystal_I2C.h>       
LiquidCrystal_I2C lcd(0x27,16,2);
//Define stepper motor connections
#define dirPin 3
#define stepPin 5
//Create stepper object
AccelStepper stepper(1,stepPin,dirPin); //motor interface type must be set to 1 when using a driver.
void INTERRUPT()
{
  REV++;
}
void setup()
{
lcd.init();                       
lcd.init();
lcd.backlight();
  Serial.begin(9600);
  attachInterrupt(1, INTERRUPT, RISING);
  stepper.setMaxSpeed(1200); //maximum steps per second
}
void loop()
{
  stepper.setSpeed(-1200); //steps per second
 stepper.runSpeed(); //step the motor with constant speed as set by setSpeed()
  delay(1000);
  detachInterrupt(0);                   
  TIME = millis() - PREVIOUS;          
  RPM_VALUE = (REV/TIME) * 60000;       
  PREVIOUS = millis();                  
  REV = 0;
  Serial.print("RPM = ");
  Serial.println(RPM_VALUE);
lcd.setCursor(0,0);
lcd.print("   Tachometer   ");
lcd.setCursor(0,1);
lcd.print("RPM: ");
lcd.setCursor(5,1);
lcd.print(RPM_VALUE);
lcd.print("   ");
  attachInterrupt(1, INTERRUPT, RISING);
}

Hi @mikeysampoerna,

to make sure to post your code in a more readable way you should use the "code tags" or copy the code from the Arduino IDE using the "copy for forum" menue entry ...

You'll find the code tags in the post editor menue:

image

It is this button:
image

float REV = 0;
int RPM_VALUE;
int PREVIOUS = 0;
int TIME;
#include <AccelStepper.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
//Define stepper motor connections
#define dirPin 3
#define stepPin 5
//Create stepper object
AccelStepper stepper(1, stepPin, dirPin); //motor interface type must be set to 1 when using a driver.
void INTERRUPT()
{
  REV++;
}
void setup()
{
  lcd.init();
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);
  attachInterrupt(1, INTERRUPT, RISING);
  stepper.setMaxSpeed(1200); //maximum steps per second
}
void loop()
{
  stepper.setSpeed(-1200); //steps per second
  stepper.runSpeed(); //step the motor with constant speed as set by setSpeed()
  delay(1000);
  detachInterrupt(0);
  TIME = millis() - PREVIOUS;
  RPM_VALUE = (REV / TIME) * 60000;
  PREVIOUS = millis();
  REV = 0;
  Serial.print("RPM = ");
  Serial.println(RPM_VALUE);
  lcd.setCursor(0, 0);
  lcd.print(" Tachometer ");
  lcd.setCursor(0, 1);
  lcd.print("RPM: ");
  lcd.setCursor(5, 1);
  lcd.print(RPM_VALUE);
  lcd.print(" ");
  attachInterrupt(1, INTERRUPT, RISING);
}

Alright, thx for the info

That's much better; I forgot to tell you also to properly format your code (that's done by ctrl T in the IDE) before providing the copy. That also improves readability (and avoids some comments by other forum members :wink: ).

Actually on a first glance some parts of your loop() code do belong into setup() as they have to be performed once, e.g. the attachInterrupt() and detachInterrupt() functions also the setSpeed/runSpeed functions ...

In general it looks as if the code was copied together from different sources?!?

Yeah, the code was copied from different sources, I just combined it together, ehhehe. For the setspeed and runspeed, i thought it must be in the void loop button to make it keep moving?

I understand ... You are in a trial 'n error phase without really trying to learn about Arduino and C++ first. I'd recommend to do this first because it improves successful coding

E.g. variables to store millis() data should (must) be of type unsigned long (int is just too small). :wink:

And it is always a good idea to try out existing code examples and then step by step move from there into unknown grounds. If the steps are too wide it is much harder to find the point where the error(s) come(s) into play ...

do you need

    stepper.run();

So this code will aready read the steps done:

volatile unsigned long REV = 0;
int RPM_VALUE;
unsigned long previous = 0;
unsigned long Time;
#include <AccelStepper.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
//Define stepper motor connections
#define dirPin 3
#define stepPin 5
#define isrPin 2
//Create stepper object
AccelStepper stepper(1, stepPin, dirPin); //motor interface type must be set to 1 when using a driver.

void INTERRUPT()
{
  REV++;
}
void setup()
{
  lcd.init();
  lcd.init();
  lcd.backlight();
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(isrPin), INTERRUPT, RISING);
  stepper.setMaxSpeed(1200); //maximum steps per second
  stepper.setSpeed(200); //steps per second
  stepper.runSpeed(); //step the motor with constant speed as set by setSpeed()
  REV = 0;
  lcd.setCursor(0, 0);
  lcd.print(" Tachometer ");
  lcd.setCursor(0, 1);
  lcd.print("REV: ");
  lcd.setCursor(5, 1);
  lcd.print(REV);
  lcd.print(" ");
}
void loop()
{
  stepper.runSpeed();
  Serial.print("REV = ");
  Serial.println(REV);
  lcd.setCursor(5, 1);
  lcd.print(REV);
  lcd.print(" ");
}

Just make sure to connect (shortcut) pin 5 with pin 3 of your arduino!

If you like you can test the code on https://wokwi.com/projects/335798078805115475

Next would be to add the parts to read the millis() and calculate RPM from REV and time between measurements ... :wink:

Thx for sharing your code. I will add the parts to read the millis() and rpm. I have tested the code that you sent, the stepper motor was running but it was very slow. I have increased the Serial.begin and stepper.setspeed but it was still slow. I used the IR proximity sensor and detected 0 revo since the speed was slow.

My bad, the rev in the lcd is working perfectly. Its just the stepper motor that seems to run slow.

This should do what you want (if RPM => Rounds Per Minute!):

#include <AccelStepper.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

//Define stepper motor connections

const byte dirPin  = 3;
const byte stepPin = 5;
const byte isrPin  = 2;
const int maxSpeed           = 1200;
const int StepsPerRevolution = 200;
const int StepsPerSecond     = 200;

//Create stepper object
AccelStepper stepper(1, stepPin, dirPin); //motor interface type must be set to 1 when using a driver.

volatile unsigned long Steps = 0;

void INTERRUPT()
{
  Steps++;
}

void setup()
{
  lcd.init();
  lcd.backlight();
  Serial.begin(115200);
  attachInterrupt(digitalPinToInterrupt(isrPin), INTERRUPT, RISING);
  stepper.setMaxSpeed(maxSpeed); //maximum steps per second
  stepper.setSpeed(StepsPerSecond); //steps per second
  lcd.setCursor(0, 0);
  lcd.print(" Tachometer ");
  lcd.setCursor(0, 1);
  lcd.print("RPM: ");
  lcd.setCursor(5, 1);
  lcd.print(0);
  lcd.print(" ");
}
void loop()
{
  stepper.runSpeed();
  calcAndPrintRPM();
}

void calcAndPrintRPM(){
  static unsigned long lastTime = 0;
  unsigned long Interval = 1000;
  if (lastTime == 0) {  // Do not provide data on the first entry to this function
    lastTime = millis();
    return;
  }
  if (millis()-lastTime > Interval){
    lastTime = millis();
    int rpm_value = round((Steps * 60000.0) / StepsPerRevolution / Interval); 
    Steps = 0;
    Serial.print("RPM = ");
    Serial.println(rpm_value);
    lcd.setCursor(5, 1);
    lcd.print(rpm_value);
    lcd.print(" ");
  }  
}

Again you can check it out on https://wokwi.com/projects/335803892223705684
if you like.

Some words to the changes:

  • Introduced const byte and const int instead of #define (Reason: This way the compiler will not allow changes of their values inside the code and avoid possible problems.)
  • Introduces "StepsPerRevolution" which define how may steps arte required for one complete turn of the stepper axis. This is required if RPM is actually "Rounds Per Minute"!
  • Introduced StepsPerSecond to define the speed
  • Separated the calculation and printing of RPM in a single function. The calculation is done very Interval msecs to ensure a fixed (and hopefully long enough) measurement time.

Another hint:

What type of stepper motor do you use?

And yes: The ISR counts the pulses on the isrPin / stepPin, it does not know what the motor is doing with it ...

Is rounds per minute the same as rotations per minute? Thank You for sharing your code and helping me out !

Nema stepper 23

Rounds and Rotation or Revolution per Minute is the the same (the abbreviation RPM = Rounds Per Minute comes from the "old" turntables if you know what I am talking about :wink: ).

  • The REV in your original code (or Steps in my) are counting the rising edges of pulses at steh stepPin.
  • A stepper motor has a certain angle per (full) step that it moves. Or the other way around a number of steps per full rotation.

NEMA 23 has 1.8° per step => 200 steps per one rotation (see const int StepsPerRevolution = 200).

So if you calculate RPM from the steps in a certain time interval it is

  • Interval => Time interval between measurements in [msec]
  • Steps => No of steps performed during Interval
  • StepsPerRevolution => Steps required for one complete 360° rotation

RPM = (Steps * 60000) / StepsPerRevolution / Interval;

Which you can interpret as

  • StepsDonePerMsec = Steps / Interval;
  • StepsPerMinute = StepsDonePerMsec * 60000;
  • RotationsPerMinute = StepsPerMinute / StepsPerRevolution;

Thx for sharing the code. The code ran well. The last issues that I have is that even when I change the steps per second, the rpm shown in the lcd is still the same when it is 200.

That is hard to investigate from remote ...

Are you sure

  • You use the sketch from post 11?
  • You are making the change to "const int StepsPerSecond = 200;" to e.g. "const int StepsPerSecond = 100;", recompile and upload to your Arduino?

What RPM does it display for "const int StepsPerSecond = 200;" ?
What for 100 or 400?

I am sure that I used the sketch from post 11. When i change the const int to 100 and 400, the rpm still shows an rpm of 15

First of all:

  • Does the stepper axis rotate significantly quicker or less if you change the StepsPerSecond?
  • What does the RPM show if you remove the cable between pin 5 and pin 2?

And then to get further it would be required to know a little more your hardware setup:

  • What Arduino board?
  • What driver electronics?
  • How is your hardware wired?

(And sorry for probably asking nasty questions ... Sometimes it is a small thing causing the problem ...)

Hi again, when i change the steps per second from 200 to 400, the steper axis doesnt rotate significantly quicker, however if I were to change it to 1000, the stepper does rotate quicker. Also what do you mean by removing the cable between pin 2 and 5? For the arduino board, I am using a arduino uno, for the driver I am using TB6560.

Thank You for helping me out!