Engineers Garage

  • Projects and Tutorials
    • Electronic Projects
      • 8051
      • Arduino
      • ARM
      • AVR
      • PIC
      • Raspberry pi
      • STM32
    • Tutorials
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Products News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • Digi-Key Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • EE Resources
    • DesignFast
    • LEAP Awards
    • Oscilloscope Product Finder
    • White Papers
    • Webinars
  • EE Learning Center
  • Women in Engineering

Motion Controller using Stepper Motor

By Ashutosh Bhatt

 

This system is the example of close loop control system to control the speed of stepper motor constant. The speed of stepper motor is sensed and feedback to controller. Controller will compare it with set value and if there is deviation then it will either increase or decrease the speed.

 

In most of the industries the constant speed of motor is required and that should not be fall / exceed beyond specified limit. to get the precise RPM and control stepper motor is the best.

Mechanical arrangement: –

Motion Controller using stepper motor Mechanical Arrangement

As shown in above figure on the fix base, there is a laser on one side and LDR with pulse generator on other side. Both are housed in wooden cabinet. The agreement is made such a way that the laser beam straightforward falls on LDR. The stepper motor is placed on top of laser as shown. The slotted wheel is coupled with the shaft of motor. The wheel is such a big that it can interrupt the laser beam falling on LDR. Now as the motor rotates the slotted wheel also rotates. The beam will fall on LDR only when the slot comes. This will produce one pulse. So every time when slot come in line with LDR and laser, one pulse is produced. Thus the rotation of motor is converted in to pulse that can be counted.  

The complete system is very big to accommodate in one page so I am dividing it in to three different section and these sections are as follows. Please click on the link to see detail description of each section.

system block diagram

stepper motor control section

RPM counting section

 Motion Control System

Motion Control System Block Diagram 

 

The figure given below shows complete block diagram of the system

Motion Control System Block Diagram

The main parts of the systems are 2 micro controllers 89C51 and 89C2051 from which 89C51 is main controller and the other one is auxiliary controller. Rest of the parts are LCD, stepper motor driver, IC555, push buttons laser and LDR. Apart form these some LEDs are also used at both sides for indication purpose. Complete system is divided in to two parts stepper motor control section and RPM counting section.

Stepper motor control section:-

The main controller 89C51 performs all following tasks.

·   It takes user inputs through four push buttons like starting / stopping of motor and increasing or decreasing the speed

·    Displays set RPM and current RPM on LCD

·    Receives the RPM count serially from auxiliary controller

·    Give different indication on LEDs

·    Drives stepper motor at the RPM set by user

RPM counting section: –

Here IC 555 is used as monostable multivibrator and it will generate pulse output corresponding to revolution of motor. These pulses are fed to 89C2051 that counts these pulses for calculated time and after counting final RPM it will send this final count serially to main controller.

Stepper motor control section

The figure given in Circuit Diagram Tab 1 shows actual schematic diagram of this section.

As shown in figure major components are micro controller 89C51, LCD (16 X 2), and ULN2003A chip. 

Connections: – four push buttons s1 – s4 are connected with P1 pins P1.0 – P1.3. The data pins of LCD are connected with port P0 and three control signals EN, Rs & RW are connected with P3.1, P3.2 & P3.3 respectively. Rx pin (P3.0) is connected with Tx pin of auxiliary controller (89C2051) of RPM counting section. The lower nibble of port P2 drives stepper motor through ULN2003A chip. Four LEDs are connected with upper nibble of port P2 for different indications. Reset switch RST is connected as shown with master reset pin (9) of 89C51. A 12 MHz crystal is connected on pin no 18 & 19.

Operation:-

Four push buttons are used for following functions

  • S1: – to start stepper motor
  • S2: – to stop stepper motor
  • S3: – increase RPM
  • S4: – decrease RPM  

Four LEDs are used for following indication

  • L1(Green LED): – indicated motor is running by blinking
  • L2(Red LED): – indicates motor is stop
  • L3(Blue LED): – blinks when RPM is increased/decreased
  • L4(yellow LED): – blinks when data byte is received 

Initially the motor is stop (indicated by Red LED) and LCD displays set RPM. When S1 is pressed motor will start rotating at set RPM and it is indicated by blinking of Green LED. As the motor starts the interrupt is generated in RPM counting section and it will start counting pulses. After 10 sec it will count RPM and return the count. This count is displayed as current RPM on LCD. After every 10 sec this cycle repeats. Mean while if any one increases or decreases set RPM it will be displayed on LCD. For accurate counting every time when RPM is changed one has to reset auxiliary controller to start counting again.  

 Software

Software: –

Whole software can be subdivided in to following sections

  • Initialization
  • User inputs through keypad
  • LCD interfacing
  • Stepper motor control
  • Serial data reception 

The main function handles initialization and keypad interfacing. For rest we have different functions. LCD interfacing has four different functions, three functions to control stepper motor and interrupt subroutine to receive data through serial port.

 

Initialization: –

  • First both timer/counters are initialized. T0 as 16 bit counter to count external pulses and T1 as 16 bit timer to set baud rate for serial communication.
  • Then serial communication mode is initialized.
  • Ports are initialized as input or output like P1 as input and rests are as output. 
  • Initialization of LCD as 

Keypad interfacing: –

  • Initially program waits for any key press. It continuously poles port P1
  • When any key is pressed it will jump to that subroutine.
  • While rotating a motor continuously, it will again pole P1 for any key press if the key is pressed it will come out of the loop and jump to that subroutine.
  • After subroutine is complete it will again start rotating motor (if ‘stop’ key is not pressed) 

LCD interfacing: – it has five different functions

  • Writedat: this function sends data on D0-D7 that is to be displayed on screen
  • Writecmd: this function sends different commands on D0-D7 that will configure LCD
  • Writestr: this function writes whole string on LCD screen
  • Busy: this function checks busy flag of LCD. If LCD is busy no data or command is sent to it. It will be only sent when busy flag is clear
  • Display: this function first converts any HEX value into decimal and then convert this decimal value into ASCII format to display it on LCD screen 

Stepper motor control: – there are three functions

  • Rotate: this function continuously rotates the motor by sending sequential pulses (with desire delay in between) till any key is not pressed. Also it blinks LED L1 at a rate of PRF (Pulse repetition frequency)
  • Spdinc: this function increases RPM by decreasing the delay given in between pulses to the motor
  • Spddec: this function decreases RPM by increasing the delay given in between pulses to the motor 

The last function is actually interrupt subroutine that is called automatically when any data byte is received serially. Because the auxiliary controller (RPM counting section) sends three digits of RPM count (like 120, 062,050 etc.) this function is called thrice. Every time it stores the digit in to memory and finally when all digits are received it will display it as “current RPM” on LCD.

 

 RPM Counting Section

RPM Counting Section

The schematic diagram of RPM counter is as shown in Circuit Diagram Tab2.

There are only two major components one is IC555 and other is micro controller 89C2051. As explained earlier function of IC555 is to generate pulses according to the revolutions of motor. These pulses will be given to controller. It will count the pulses calculate the RPM and send it to main controller.

Connections: – IC 555 is configured in monostable mode with time period of 10 ms (this depends upon components R1 & C1). LDR is biased in such a manner that when laser light falls on it, it will trigger IC 555. The output of IC 555 is inverted through transistor (2N2222A type) and connected with INT1 (pin no.-7) and T0 (pin no.-8) pins of controller. One LED (L1) is also connected to output of IC 555. Two more LEDs L2 and L3 are connected with P1.7 (pin no.-19) and P1.6 (pin no.-18). 12 MHz crystal is connected as shown. Push button switch S1 is connected with reset pin of controller.

Operation: –

·         As motor starts rotating the laser light will fall on LDR from the slotted wheel

·        This will trigger IC555 every time when motor completes one revolution and it will generate one pulse that is indicated by LED L1

·        As the first pulse arrives it will generate an interrupt for controller and immediately it will start counting these pulses. This is indicated by LED L2.

·        Controller will count these pulses for the period of 10 sec. after then it will store the count and multiply it by 6 to have final RPM count (if we count external pulses for 1 sec then to get RPM we have to multiply it by 60 as 1 RPM=60 RPS but here we are counting external pulses for 10 sec so count×6 = RPM).  

·        Finally after getting the RPM controller will send this value serially to main controller and give indication on LED L3.

·        Again if motor is running interrupt will arrive and the same process repeats.

Software: –

The heart of this section is the program that is embedded in to 89C2051. The program is written in C languageand it is compiled by keil (IDE) cross compiler. As we already know what is the function of microcontroller just we have to write the suitable code for it. Whole program is made up of four different functions. In the main function there is only initialization rest all the tasks are performed by these functions. And these functions are int1, delay1, delay2 and hextodesi. Let’s see what each function is for.

Int1: – its interrupt function and it is automatically called when external interrupt 1 arrives, means when a high to low edge occurs on EXT1 (P3.3 or pin no. 7). It performs only one task that is counting RPM. For this it will start internal counter (T0) then generate 10 sec delay, stop counter, store and multiply the count by 6 to get the final RPM count and then call the hextodesi function to finish rest of the tasks.

Delay1: – this is 100 ms delay that is used in between transmitting characters serially one by one through Tx pin

Delay2: – this is 10 sec delay that is generated to count external pulses. It is called after internal counter is start and when this delay finishes counter will stop counting

Hextodesi: – whatever the count value we shall get will be in hex format. So this function first converts this hex value into equivalent decimal value and then because we want to display this value on to LCD again this decimal value is converted in to ASCII format. Finally these ASCII values are transmitted serially one by one through Tx pin.

Finally in the main program performs these tasks

  • Initialization of timer modes. T0 as counter and T1 as timer
  • Initialization of serial communication mode
  • setting of baud rate
  • enabling of external interrupt 1

 

 

 

Project Source Code

 

Project Source Code

###

Code For Motion Control 

#include<reg51.h>

#include <string.h>

sbit rs = P3^7;                   // rs pin of LCD

sbit en = P3^5;                   // en pin of LCD

sbit rw = P3^6;                   // rw pin of LCD

sbit b = P0^7;                    // busy flag

sbit stp=P2^5;                    // stop indicator

sbit spd=P2^6;                    // RPM change indicator

sbit rcv=P2^7;                    // byte received indicator

unsigned int f=0,d,r,c=0;

unsigned char data d1,d2,d3;

 

void writecmd(unsigned char a);// function initializations

void writedata(unsigned char b);

void busy(void);

void writestr(unsigned char *s);

void send(void);

void dely(void);

void rotate(void);

void delay(int);

void spdinc(void);

void spddec(void);

void display(unsigned int);

 

void recv(void) interrupt 4       // serial interrupt function

  {

     rcv = 1;                     // indication

     RI=0;                        // clear receive flag

     c++;                         // count received digits

     if(c==1) d1=SBUF;            // store them one by one

     else if(c==2) d2=SBUF;

     else if(c==3)                // when all three received

       {     

          d3=SBUF;

          c=0;                    // reset count

          writecmd(0xC0);

          writestr("Current RPM= ");   // display "current RPM"

          writedata(d1);          // and display all bytes one by one

          writedata(d2);

          writedata(d3);

       }  

     rcv = 0;

  }

void spdinc()                     // increase RPM

  {

   spd=1;                         // indication

   dely();                        // debounce delay

   if(d>5)                        // decrease delay till it becomes

     {

    d=d-5;                       // minimum

          r=1250/d;              // calculate RPM

        writecmd(0x80);          // display it as "set RPM"

         writestr("set RPM = ");

          display(r);      

    }

     else if(d==5)               // if delay is minimum

       {

         writecmd(0x80);

        writestr("maximum RPM  ");    // display message

       }

   }

void spddec (void)                // decrease RPM

{                

     spd=1;                       // indication

    dely();                       // debounce delay

     if(d<45)                     // increase delay till it becomes

       {

          d=d+5;                  // maximum                 

          r=1250/d;               // calculate RPM

          writecmd(0x80);

         writestr("set RPM = ");  // display it as "set RPM"

          display(r);     

      }

     else if(d==45)               // if delay is maximum

       {

         writecmd(0x80);

        writestr("minimum RPM  ");    // display message    

       }

 }

void delay(int c)

 {

     int k;

     TL0 = 0x17;             // load timer with 64535

     TH0 = 0xFC;

     TR0 = 1;                // start timer

     for(k=0;k<c;k++)        // count no of overflows

       {

          while(TF0==0);     // timer will overflow after 1 ms

          TF0 = 0;           // clear timer overflow flag

          TL0 = 0x17;        // and reload timer till desire delay

          TH0 = 0xFC;        // is complete

       }

     TR0 = 0;                // stop timer

}

 

void rotate()                // rotate motor

{

  while(P1==0xFF)            // till any key is not pressed

   {

     P2=0x11;                // apply pulse sequence

     delay(d);               // with desire delay

     P2=0x12;

     delay(d);

     P2=0x04;

     delay(d);

     P2=0x08;

     delay(d);

   }

}

void display(unsigned int z)  // display ASCII char on LCD

  {

     int z1,a,ASCII[3];      // convert decimal no into ASCII

    if(z>=100)               // if its 3 digit number

       {

          a=2;

          while(z>10)        // till it is greater then 10

          {       

              z1=z%10;      // separate its all digits

              ASCII[a]=z1+0x30;  // and convert it into ASCII

              z=z/10;

              a--;

          }

          ASCII[0]=z+0x30;

       }

     Else                   // if its 2 digit number

       {

          z1=z%10;          // separate both digits

          ASCII[2]=z1+0x30;  // convert them into ASCII

          z=z/10;

          ASCII[1]=z+0x30; 

          ASCII[0]=0x30;// display first digit as ‘0’

       }

     writedata(ASCII[0]);         // display all three digits

     writedata(ASCII[1]);

     writedata(ASCII[2]);

  }

void dely(void)              //  key debounce delay

  {

    unsigned int x,y;

    for(x=0;x<100;x++)

         for(y=0;y<1000;y++);

  }

void writecmd(unsigned char a)    // send command to LCD

{

     busy();                 // check busy flag

     rs = 0;                 // clear rs to select command register

     rw = 0;                 // clear rw pin

     P0 = a;                 // send command

     en = 1;                 // strobe display

     en = 0;

}

void writedata(unsigned char b)   // send data to LCD

{

     busy();                 // check busy flag

     rs = 1;                 // set rs to select data register

     rw = 0;                 // clear rw pin

     P0 = b;                 // send data     

     en = 1;                 // strobe display

     en = 0; 

}

void busy()                  // check  busy flag

{

     en = 0;                 // disable LCD

     P0 = 0xFF;              // consider P0 as input

     rs = 0;                 // select data register

     rw = 1;                 // read LCD

     while(b==1)             // loop till busy flag is 1

     {

      en=0;

      en=1;

     }

     en=0;                   // disable LCD

}

void writestr(unsigned char *s)   // write message string on LCD

{

     unsigned char l,i;

     l = strlen(s);          // get length of message

     for(i=1;i<l;i++)

     {

          writedata(*s);     // send all the char one by one

          s++;    

     }

}

void main()

  {

    TMOD = 0x21;             // initialize timer and counter

    SCON=0x40;               // initialize serial communication

    TH1=0xF3;                // set baud rate to 9.6 KBPs

    TL1=0xF3;    

    TR1=1;                   // start timer

     IE=0x90;                // enable serial interrupt

    REN=1;                   // enable reception

    P2=0x00;                 // P2 and P0 as output

    P0=0x00;

    writecmd(0x3C);          // initialize LCD     

    writecmd(0x0E);   

    writecmd(0x01);         // clear LCD memory and home cursor

    d=25;                   // set 50 RPM initially

    r=1250/d;

    writecmd(0x80);

    writestr("set RPM = "); // display message

    display(r);             // and RPM

begn:stp=1;                 // stop indication

     P1=0xFF;

    while(P1==0xFF);        // wait until is pressed

loop:switch(P1)

      {

          case 0xFE:

               dely();

               P1=0xFF;

               f=1;         // set the flag and     

               rotate();    // start rotating motor

              break;

          case 0xFD:

               P2=0x00;     // stop the motor and

               f=0;         // reset the flag

               dely();

               break;

          case 0xFB:               

               spdinc();    // increase RPM

               P1=0xFF;

               if(f==1) rotate();// if motor is rotating

               break;            // keep continue

          case 0xF7:            

               spddec();         // decrease RPM

               P1=0xFF;                   

               if(f==1) rotate();// if motor is rotating

               break;            // keep continue

        }

if(f==1) goto loop;               // if motor is stop wait for

else goto begn;                   // key press

}

Code For RPM Counter

 

#include<reg51.h>                         // include 8051 register file

 

 

 

 

unsigned char data tmp;                   // define any temperory register

sbit led1 = P1^7;                         // define led1 as 7th bit of P1

sbit led2 = P1^6;                         // define led2 as 6th bit of P1

 

void delay(void);                         // function initialization

void dely(void);

void hextodesi(unsigned char x);

void intr1(void) interrupt 2              // external interrupt 1 function

  {  

      EX1=0;                              // disable all interrupts for 10 sec

      led1=0;                             // LED indication

      TH0=0x00;                           // reset counter

      TL0=0x00;

      TR0=1;                              // start counter

      delay();                            // give 10 sec delay

      TR0=0;                              // stop counter

      tmp=TL0;                            // store count

      tmp=tmp*6;                          // multiply it by 6

      hextodesi(tmp);                     // convert it into ASCII

      led1=1;                               // indication off

      EX1=1;                              // again enable interrupts

 }

void hextodesi(unsigned char x)     // convert hex to desi and then to ASCII

  {

      unsigned int tmp1,tmp2,t,t1,i,k;

      unsigned char asci[3];

      tmp1 = (x & 0x0F);                  //get lower nibble of hex value

      tmp2 = x >> 4;                      // get upper nibble of hex value

      tmp2 = tmp2*16;                     // multiply upper nibble by 16 and

      t = tmp1+tmp2;          // add upper and lower nibble to get decimal value

      if(t>=100)                          // if number is greater then 100

        {

            i=2;                          // take three digits

            while(t>10)             // get each digit one by one till it is

            {                             // greater then 10

                  t1=t%10;

                  asci[i]=t1+0x30;        // convert them it to ASCII

                  t=t/10;

                  i--;

            }

            asci[0]=t+0x30;

        }

       else                               // if its less then 100 then

        {                                                  

            t1=t%10;

            asci[2]=t1+0x30;

            t=t/10;

            asci[1]=t+0x30;       

            asci[0]=0x30;                 // take first digit as zero       

        }

     for(k=0;k<=2;k++)                    // one by one send all three digits

        {

            led2=0;

            SBUF = asci[k];

            while(TI==0);

            TI=0;

            led2=1;

            dely();

         }

  }             

void delay()                              // generate delay of aprox 10 sec

  {

    int i,j;

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

        for(j=0;j<10000;j++);

  }

void dely()                               // generate delay of aprox 100 ms

  {

    int l;

      for(l=0;l<10000;l++);

  }

void main()

  {

    TMOD=0x25;    // initialize T0 as 16 bit counter and T1 as 16 bit timer

      SCON=0x40;                          // serial communication mode 1

      TH1=0xF3;               // load the count to set buad rate of 9.6 KBPS

      TL1=0xF3;

      TR1=1;                              // start timer

      IE=0x84;                            // enable external interrupt 1

      while(1);                           // continuous loop

 

 

###

 


Circuit Diagrams

new-step-cnt_0
RPM


Filed Under: Electronic Projects
Tagged With: ldr, motion control, motor, stepper motor
 

Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.



Tell Us What You Think!! Cancel reply

You must be logged in to post a comment.

HAVE A QUESTION?

Have a technical question about an article or other engineering questions? Check out our engineering forums EDABoard.com and Electro-Tech-Online.com where you can get those questions asked and answered by your peers!


Featured Tutorials

  • Designing Gate Driver Circuit and Switching Mechanism for Modified Sine Wave Inverter – (Part 9/17)
  • Completing Modified Sine Wave Inverter Design with Full Bridge Circuit and Step Up Transformer – (Part 10/17)
  • Designing an Offline UPS – Part (12 /17)
  • How to reduce Switching Time of a Relay – (Part 15/17)
  • Testing MOSFET – (Part 16/17)
  • Driving High Side MOSFET using Bootstrap Circuitry – (Part 17/17)

Stay Up To Date

Newsletter Signup

Sign up and receive our weekly newsletter for latest Tech articles, Electronics Projects, Tutorial series and other insightful tech content.

EE Training Center Classrooms

EE Classrooms

Recent Articles

  • New automotive radar sensor enables reliable in-cabin monitoring system
  • TI breaks ground on 300-mm semiconductor wafer-fabrication plants in Texas
  • New wireless AR Smart Viewer reference design
  • Infineon launches scalable and wireless charging platform with configurable controllers
  • First single-core MPU with MIPI CSI-2 camera interface and audio

Most Popular

5G 555 timer circuit 8051 ai Arduino atmega16 automotive avr dc motor display Electronic Part Electronic Parts Fujitsu ic infineontechnologies integratedcircuit Intel IoT ir lcd ldr led maximintegratedproducts microchip microchiptechnology Microchip Technology microcontroller microcontrollers mosfet motor powermanagement Raspberry Pi remote renesaselectronics renesaselectronicscorporation Research samsung semiconductor sensor software STMicroelectronics switch Technology vishayintertechnology wireless

RSS EDABOARD.com Discussions

  • MAX2771 digital output processing
  • request for a good manual on rectangular waveguide feeding network
  • RC Extraction with black box option
  • what is internal pin in a standard cell
  • MOSFET ORing circuit simulation (LTspice)

RSS Electro-Tech-Online.com Discussions

  • NXP i.MX8 board vs Raspberry Pi?
  • Ampro 16mm Stylist projector woes.
  • Need help using a common power supply for two devices
  • Multistage BJT amplifier
  • Help me to start 24V BLDC (Star winding)
Engineers Garage
  • Analog IC TIps
  • Connector Tips
  • DesignFast
  • EDABoard Forums
  • EE World Online
  • Electro-Tech-Online Forums
  • Microcontroller Tips
  • Power Electronic Tips
  • Sensor Tips
  • Test and Measurement Tips
  • 5G Technology World
  • About Us
  • Contact Us
  • Advertise

Copyright © 2022 WTWH Media LLC. All Rights Reserved. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of WTWH Media
Privacy Policy | Advertising | About Us

Search Engineers Garage

  • Projects and Tutorials
    • Electronic Projects
      • 8051
      • Arduino
      • ARM
      • AVR
      • PIC
      • Raspberry pi
      • STM32
    • Tutorials
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Products News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • Digi-Key Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • EE Resources
    • DesignFast
    • LEAP Awards
    • Oscilloscope Product Finder
    • White Papers
    • Webinars
  • EE Learning Center
  • Women in Engineering