Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] How to count encoder pulses using PIC

Status
Not open for further replies.

RuH_iranga

Junior Member level 3
Joined
Nov 4, 2010
Messages
31
Helped
7
Reputation
14
Reaction score
6
Trophy points
1,288
Location
sri lanka
Activity points
1,480
Component:
16f877
POLOLU encoder motor Pololu - 131:1 Metal Gearmotor 37Dx57L mm with 64 CPR Encoder 2096 pulses per one shaft revolution.

Use RB0 interrupts and turn on the PORTB pull-up resistors.
use MikroC language.
Code:
int count=0;           // This count use in interrupt routine

void interrupt()               // enter when RB0 Falling
{
  if(portb.f0&portb.f1)         // By checking B0 and B1, Position and Direction Find
  {count++;                     // If "+" direction
  }
  else                          // If "-" direction
  {count--;
  }
  INTCON.INTF=0;                // Clear flag
}

void main()
{
     Pwm_Init(5000);
     PWM_Start();
     TRISB=0b11111111;          // B0 and B1 encoder inputs
     TRISD=0b00000000;          // Motor Control Pin
     INTCON=0b11010000;         // enable RB0 interrupts
     OPTION_REG=0b01000000;     // Enable portB internal PULL-UP resistors
                                // And Rising edge of RB0 int
     Pwm_Change_Duty(240);      // Whatever speed
     portd.f1=1;                // Motor drive to "+"
     portd.f0=0;

     while(1)
     {

         if (count>4192)    // Count exceeds 4192(2 round), Stop
         {
           portd.f1=0;
           portd.f0=0;
         }

         
     }
}

By changing RD0 and RD1 you can change motor direction, then it should be reduced the count. and also change the (count<-4192) you can ensure that program detect the position as well as direction. this just reading encoder and you can use it with your application. Also possible to use 10k external Pull-UPs on B0 and B1.


Thanks.:smile:
 

why not make a counter on the code?

when going CW you put:

Count_step= Count_step + 1; // the +1 is the length of the step it can be any number

when going CCW just go to:

Count_step=Count_step -1;

hope it helps ^^
 
Hi RuH_iranga

I did an encoder reader like that.
The only sugestion I could give is to treat the case when encoder speed is to high.
The change to this code wolud be a mapping to all positions possibility (00/10/11/01) at interrupt funcion.

Hope this help.

+++
 
Interfacing Micro-controllers with Incremental Shaft Encoders
 

Attachments

  • ise.pdf
    131.1 KB · Views: 210

    V

    Points: 2
    Helpful Answer Positive Rating

    RuH_iranga

    Points: 2
    Helpful Answer Positive Rating

    sherazi

    Points: 2
    Helpful Answer Positive Rating
Thank you all of you

now I'm trying to develop this to 2 encoders, I think it is possible with B0, B1, B2 interrupts.
My project is a stabilization platform, I'll put my project after completing.
Thanks

---------- Post added at 10:44 ---------- Previous post was at 10:20 ----------

Hi all
I found that 18f452 INT0, INT1, INT2 interrupts may be useful.

---------- Post added at 11:41 ---------- Previous post was at 10:44 ----------

This is for 18f452 for two Encoders
Code:
int count1=0;           // This count use in interrupt routine
int count2=0;

void interrupt()               // enter when RB0 and RB1 Rising
{
  if(INTCON.INT0IF==1)
  {
         if(portb.f0&portb.f2)      // By checking B0 (YELLOW) and B2(WHITE), Position and Direction Find
         {count1++;                 // If "+" direction
         }
         else                       // If "-" direction
         {count1--;
         }
         INTCON.INT0IF=0;
  }
  if(INTCON3.INT1IF==1)
  {
         if(portb.f1&portb.f3)      // Check RB1 and RB3 for SECOND ENCODER
         {count2++;
         }
         else
         {count2--;
         }
         INTCON3.INT1IF=0;
  }

                         // Clear flag
}

void main()
{
     Pwm_Init(5000);
     PWM_Start();
     Pwm_Change_Duty(200);
     
     TRISB=0b11111111;          // B0, B1, B2, B3 encoder inputs
     TRISD=0b00000000;          // Motor Control Pin

     INTCON.GIE=1;         // enable RB0 interrupts
     INTCON.INT0IE=1;
     INTCON.INT0IF=0;

     INTCON2.RBPU=0;      // Enable portB internal PULL-UP resistors
     INTCON2.INTEDG0=1;   // RB0 RB1  edge selection
     INTCON2.INTEDG1=1;
  //   INTCON3.INT1IP=1;
     INTCON3.INT1IE=1;    // Enable RB1 INT
     INTCON3.INT1IF=0;


     portd.f1=1;                // Motor drive to "+"
     portd.f0=0;                //motor(B-diode/// R-L298)

     while(1)
     {
         if (count1>2096)    // Count exceeds 2096(1 round), Stop
         {
           portd.f1=0;
           portd.f0=0;
         }
         if(count2>2096)
         {
            portd.f1=0;
            portd.f0=0;
         }
     }
}

(please someone tell me how to add Help icon)
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top