How to program a rotary encoder to smooth the duty cycle creation

Thread Starter

Manea Nicolas

Joined Apr 14, 2016
3
Hi!
I use the following:
-PIC16F877A microcontroller
-GRAYHILL 25LB22-H MECHANICAL ENCODER as a rotary encoder

I have the following issue:
Because of the fact that the rotary encoder has only 16 pulses, I find this inefficient for the project. What I would like to do is to increment the number of pulses through coding. This is my idea:
I will use 2 variables: one to record the knob position on the rotary encoder and another one to count the number of complete rotation. The problem is that I don't know how to get feedback from the previous state of the knob as if the position is now 1 and the previous position was 15, the program will know to increment the number of complete rotations by 1 and vice-versa.

The code is the following:

Code:
#include<htc.h>

#define _XTAL_FREQ 20000000
#define TMR2PRESCALE 4
long freq;

int PWM_Max_Duty()
{
  return(_XTAL_FREQ/(freq*TMR2PRESCALE);
}

PWM1_Init(long fre)
{
  PR2 = (_XTAL_FREQ/(fre*4*TMR2PRESCALE)) - 1;
  freq = fre;
}

PWM2_Init(long fre)
{
  PR2 = (_XTAL_FREQ/(fre*4*TMR2PRESCALE)) - 1;
  freq = fre;
}

PWM1_Duty(unsigned int duty)
{
  if(duty<=16)
  {
    duty = ((float)duty/16*6)*PWM_Max_Duty();    //this is divided by 16*6 as I want to have a max of 6 complete rotations and 16 pulses per rotation
    CCP1X = duty & 2;
    CCP1Y = duty & 1;
    CCPR1L = duty>>2;
  }
}

PWM2_Duty(unsigned int duty)
{
  if(duty<=16)
  {
    duty = ((float)duty/16*6)*PWM_Max_Duty();
    CCP2X = duty & 2;
    CCP2Y = duty & 1;
    CCPR2L = duty>>2;
  }
}

PWM1_Start()
{
  CCP1M3 = 1;
  CCP1M2 = 1;
  #if TMR2PRESCALAR == 1
    T2CKPS0 = 0;
    T2CKPS1 = 0;
  #elif TMR2PRESCALAR == 4
    T2CKPS0 = 1;
    T2CKPS1 = 0;
  #elif TMR2PRESCALAR == 16
    T2CKPS0 = 1;
    T2CKPS1 = 1;
  #endif
  TMR2ON = 1;
  TRISC2 = 0;
}

PWM1_Stop()
{
  CCP1M3 = 0;
  CCP1M2 = 0;
}

PWM2_Start()
{
  CCP2M3 = 1;
  CCP2M2 = 1;
  #if TMR2PRESCALE == 1
    T2CKPS0 = 0;
    T2CKPS1 = 0;
  #elif TMR2PRESCALE == 4
    T2CKPS0 = 1;
    T2CKPS1 = 0;
  #elif TMR2PRESCALE == 16
    T2CKPS0 = 1;
    T2CKPS1 = 1;
  #endif
    TMR2ON = 1;
    TRISC1 = 0;
}

PWM2_Stop()
{
  CCP2M3 = 0;
  CCP2M2 = 0;
}

void main()
{
  unsigned int bi, rot;
  PWM1_Init(5000);
  PWM2_Init(5000);

  TRISD = 0xFF;
  PWM1_Duty(0);
  PWM2_Duty(0);
  PWM1_Start();
  PWM2_Start();
  do
  {
    bi=2^3*RB3+2^2*RB2+2^1*RB1+RB0;
                           //this is where i lack the code ideea
    PWM1_Duty(bi); 

    __delay_ms(20);
  }while(1);
}
 

MaxHeadRoom

Joined Jul 18, 2013
28,621
One way to multiply the count of a quadrature encoder is to capture the four edges, multiplying the count x4.
In a Pic this can be done by capture module, rising and falling edges.
I don't program in C however.
Max.
 

MaxHeadRoom

Joined Jul 18, 2013
28,621
The quadrature encoder consists of 2 pulses, 90° apart, and consists of four edges, two rising, two falling, if these are detected via the CCP capture module, each rising and falling edge can be detected and counted essentially increasing the resolution x4.
See sec 8 of the manual.
Also Microchip recommend this version be replaced by the 16f18877 now.
Max.
 

JWHassler

Joined Sep 25, 2013
306
Weight the pulses more heavily at high speed.
When the encoder spins rapidly, each pulse is a 5% change. When spun slowly, count them as 1% each.
 

dannyf

Joined Sep 13, 2015
2,197
I will use 2 variables: one to record the knob position on the rotary encoder and another one to count the number of complete rotation.
not really sure how that works -> in generally you cannot create information when there is none. The best alternative is to get another encoder with finer resolutions.
 

Thread Starter

Manea Nicolas

Joined Apr 14, 2016
3
not really sure how that works -> in generally you cannot create information when there is none. The best alternative is to get another encoder with finer resolutions.
Yes, that would be the easy job. I do this as a university project and buying a finer resolution rotary encoder is not an option because is more expensive
 

MaxHeadRoom

Joined Jul 18, 2013
28,621
The Quadrature pulses x4 is done consistently throughout the CNC/Motion control industry for some decades now to increase resolution.
Max.
 
Top