How to count the number of steps a stepper motor has made and update it on LCD?

Hello everyone,

I am building a programmable stepper motor. It contains arduino mega 2560, lcd keypad shield, nema 14 stepper motor, a opto interrupter sensor and a stepper motor driver (polulu DRV8825). I am stuck at one point. I want to update the lcd screen everytime the motor takes 1 step. The number of steps, speed of motor and direction will be user input. Also, I want to set the speed of the stepper motor according to the input entered using the keypad shield. But I don't know how to make this thing work. Any idea what should be the logic? Please help me out with this issue I am having.

To start, Robin2 's discussion:
http://forum.arduino.cc/index.php?topic=261445.0

Hi Larry,

Thank you for the link. The functions for a servo motor are not the same as stepper. Correct?

The two motors are completely different.
Your stepping motor can be advanced one step at a time. Lots are 1.8 degrees per step.
There are a lot of Arduino/stepping motor hits on the Internet.

Maybe look at YouTube for some stepping motor offerings.

https://m.youtube.com/results?q=stepping%20motor&sm=3

.

Ok. Thank you.

Adafruit stepping motor and LCD tutorials:

pooja2788:
Thank you for the link. The functions for a servo motor are not the same as stepper. Correct?

Also have a look at this Simple Stepper Code and at Stepper Motor Basics

The simple answer to the question in your title is to command the motor to move one step at a time and increment a variable once for every step. Then the code for your LCD can read the value in that variable and display it on the screen.

Writing to an LCD is time consuming so you probably won't want to update the display for every step unless the motor is moving very slowly. It may be sufficient to update the display once or twice per second.

Do not use the delay() function anywhere in your program.

...R

Hello Robin,

Thank you for helping me out. Well its a project I am doing for my final semester. My professor asked me to display it on the lcd for every step the motor takes. I have no choice, but to do it. What if I display the revolution instead of displaying steps? Will it help solving the problem I am having?

You say will it help with the problem I am having.

Show us your work so we can help you with that problem.

Updating your LCD faster than 3-4 times a second is useless.

.

digitalWrite(dirPin, direct2);

for (int x = 0; x < steps2200; x++)
{
digitalWrite(stepPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin, LOW);
delayMicroseconds(500);
}
delay(1000);
lcd.setCursor(2, 1);
lcd.print("Back to Home ");
digitalWrite(dirPin, !direct2);
for (int x = 0; x < steps2
200; x++)
{
digitalWrite(stepPin, HIGH);
delayMicroseconds(500);
digitalWrite(stepPin, LOW);
delayMicroseconds(500);
}
lcd.clear();
delay(200);
lcd.setCursor(0, 0);
lcd.print("Done");
delay(4000);
}

void lcdstatus()
{
// Serial.println(status);
if (status == 1)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter # of steps");
lcd.setCursor(0, 1);
lcd.print(steps1);
}
if (status == 2)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter Speed");
lcd.setCursor(0, 1);
lcd.print(speed1);
}
if (status == 3)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter direction");
lcd.setCursor(0, 1);
lcd.print(direct1);
}
if (status == 4)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Ready to go");
lcd.setCursor(0,1);
lcd.print("Press Select Key");
}
}

This is the logic I have written for using the lcd keypad shield. I was trying to put the steps2 value in a new variable and then increment it but its simply showing me the value on the lcd. Its not updating. I am not having much idea about arduino commands. Is there a way I can use a counter or limit condition to count the steps?

Please, you must show us your complete sketch. Attach your code using the </> icon on the left side of the posting menu.

You are going to have to remove delay() functions if you want a responsive project.

Are you familiar with using millis() to achieve unblocking delays, see BWD (Blink Without Delay).

Tackle this project one section at a time, when you have things working separately, put things together.

.

#include <LiquidCrystal.h>
//#include<Stepper.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int stepsPerRevolution;
const int stepPin = 32;
const int dirPin = 30;

// Here set the stepper motor rotation step to check when does the motor make one revolution//

int dim = stepsPerRevolution;

// Set the step motor number and pin
//Stepper myStepper(stepsPerRevolution, 7, 11, 12, 13);

int ans = 0;
int a = 0; //used for moving the cursor left or right.
int status=1;
int steps1=0;
int speed1=0;
int direct1=0;
int steps2=0;
int speed2=0;
int direct2=0;
int go;
int val;

void setup()
{
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  //lcd.print("Prog Step Motor");
  //Serial.begin(9600);
  //lcd.begin(16, 2);
  //lcd.print("Enter Rotations: ");

  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
}

void loop() 
{

  val = analogRead(0); // used by Lcd
  lcd.setCursor(a, 1);

    if (val < 60) 
    //Right PB.
    {
      lcd.clear();
    //
      if (status < 4)
          if (status >= 1)
          {
               status++;
               delay(200);
          }
      else
      {
      delay(200);
      }
     }
  else if (val < 200) 
  {
  //up button

    if (status == 1)
        {
          steps1++;
        }
        delay(200);
    if (status == 2)
        {
          speed1++;
        }
    if (status == 3)
      if (direct1 < 1)
        {
        if (direct1 >= 0)
          {
          direct1++;
          }
        delay(200);
        }
      }
  else if (val < 400) {
    //down button
    if (status == 1)
        {
          steps1--;
        }
        delay(200);
    if (status == 2)
        {
          speed1--;
        }
    if (status == 3)
      if (direct1 = 1)
      {
        if (direct1 >= 1)
          {
        direct1--;
          }
        delay(200);
          }

  }
  else if (val < 600) {
    //left button
    lcd.clear();
    if (status > 1)
{
      status--;
      delay(200);
  }
    else
    {
      //a--;
      delay(200);

    }
  }
  
  else if (val < 800) {
    //want to use this to save the value and move onto another function.

    //if (val = 1023)
    {


      //int val=ans;
      //Serial.println(val);
     // if (status == 1)
    
        steps2 = steps1;
        speed2 = speed1;
        direct2 = direct1;
   
      if (status == 4)
      {
        go = 1;
        lcd.print("Run the Motor");
        Serial.print("go=");
        Serial.println(go);
        runStep();

      }

       delay(200);
    }
  }
       delay(10);
       lcdstatus();
}





//myStepper.setSpeed(60);


//***********************************
//***********************************

void runStep()

{
    Serial.print("steps1=");
    Serial.println(steps1);
    Serial.print("speed1=");
    Serial.println(speed1);
    Serial.print("direct1=");
    Serial.println(direct1);
  //
    Serial.print("steps2=");
    Serial.println(steps2);
    Serial.print("speed2=");
    Serial.println(speed2);
    Serial.print("direct2=");
    Serial.println(direct2);
  // clockwise rotation

  dim = stepsPerRevolution;
  lcd.clear();
  delay(200);
  lcd.setCursor(2, 0);
  lcd.print("Motor running");
  lcd.setCursor(4, 1);
  
   if (direct2==1)
    
   lcd.print("CLW => 1");
   
   if (direct2==0)
   
   lcd.print("CCW => 0 ");
   
   
   delay(100);
  //
   digitalWrite(dirPin, direct2);
   Serial.println(steps2);
   for (int x = 0; x < steps2*200; x++)
     {
       digitalWrite(stepPin, HIGH);
       delayMicroseconds(500);
       digitalWrite(stepPin, LOW);
       delayMicroseconds(500);
     }
     delay(1000);
     lcd.setCursor(2, 1);
     lcd.print("Back to Home    ");
     digitalWrite(dirPin, !direct2);
   for (int x = 0; x < steps2*200; x++)
     {
       digitalWrite(stepPin, HIGH);
       delayMicroseconds(500);
       digitalWrite(stepPin, LOW);
       delayMicroseconds(500);
     }
   lcd.clear();
   delay(200);
   lcd.setCursor(0, 0);
   lcd.print("Done");
   delay(4000);
}

void lcdstatus()
{
  // Serial.println(status);
  if (status == 1)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Enter # of steps");
    lcd.setCursor(0, 1);
    lcd.print(steps1);
  }
  if (status == 2)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Enter Speed");
    lcd.setCursor(0, 1);
    lcd.print(speed1);
  }
  if (status == 3)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Enter direction");
    lcd.setCursor(0, 1);
    lcd.print(direct1);
  }
  if (status == 4)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Ready to go");
    lcd.setCursor(0,1);
    lcd.print("Press Select Key");
  }
}

Here is the code I have written so far.

= is not a he same as ==

if (direct1 = 1)

I know. So you are saying it should be ==? instead of =?

The 'if' function uses == you have =

= is an assignment operator
== is a comparison operator

  • Try a simple LCD sketch example to make sure you have everything connected properly.

  • What is your sketch not doing?

Its working properly. But the only thing I am having trouble with, is to update the lcd screen everytime the motor takes the steps entered by the user. And secondly I want to run the motor according to the speed entered by the user. Not to run it at a constant speed.

IMHO you need to rewrite the code to separate the different activities. Your code in loop() could be as simple as

void loop() {
   readSwitches();
   moveMotor();
   updateLCD();
}

Have a look at Planning and Implementing a Program

With the code for the different activities in different functions it will be much easier to manage and to change one part without screwing up another.

If you want a responsive program you MUST get rid of all the delay()s and use millis() to manage timing without blocking. That is illustrated in the above link and in the demo Several Things at a Time

...R

Thank you Robin. I will try it ,the way you suggested.