SilverWingz
New Member
I am currently working on a PIC16F877A(MPLAB/Hi-Tech)
I wrote a program to obtain feedback from a quadrature encoder(512 changes/rev) using a lookup table to determine direction of revolution:
The code works,however misses steps whenever the motor speed goes up a bit,which,i guess is to be expected from the LCD display routines.
That's the problem.The project is demonstration purpose,which is why i need the display(at least up to hundred counts)
and I'm a complete beginner with LCD's so i had no idea thr was any way to display wasting lesser machine cycles.
WHAT I ASK,is if the code can be further manipulated (specially the display part) as to not miss encoder steps at higher rpm's?
NOTE: I HAVE IGNORED INVALID STATES FOR NOW,DESCRIBING THEM AS 0 COUNT IN THE TABLE
I wrote a program to obtain feedback from a quadrature encoder(512 changes/rev) using a lookup table to determine direction of revolution:
Code:
#include<htc.h>
#define _XTAL_FREQ 8000000
#define RGSL RC1 /* LCD register select */
#define RW RC0 /* LCD read/write mode select */
#define EN RC2 /* LCD read/write enable */
/* function definitions */
void LCD_INIT(void);/* LCD initialistion */
void LCD_COMM(char COMM);
void main()
{
LCD_INIT(); /* lcd initialization */
LCD_COMM(0xC0); /* second row selection for display */
int old_val=0;
int new_val=0;
int out=0;
long int count=0;
int t_cnt=0,o_cnt=0,h_cnt=0;
int q[16];
q[0]=0;q[1]=-1;q[2]=1;q[3]=0; //LOOK UP TABLE FOR ENCODER
q[4]=+1;q[5]=0;q[6]=0;q[7]=-1; //LOOK UP TABLE FOR ENCODER
q[8]=-1;q[9]=0;q[10]=0;q[11]=1; //LOOK UP TABLE FOR ENCODER
q[12]=0;q[13]=1;q[14]=-1;q[15]=0; //LOOK UP TABLE FOR ENCODER
TRISB=0b11111111; /* configure PORTB pins */
PORTB=0b00000000;
while(1)
{
old_val=new_val; //storing previous state for comparison
new_val=(2*RB1)+RB0; //getting decimal from encoder binary o/p
out = q [old_val * 4 + new_val]; //deciding count increment/decrement/no change from lookup table
if(old_val!=new_val) //NOTE:I'VE IGNORED INVALID STATES,FOR NOW
{
count=count+out;
h_cnt=count/100; //hundreds count
t_cnt=(count%100)/10; //tens count
o_cnt=count%10; //ones count
//DISPLAY HUNDREDS COUNT
RGSL=1; /* data register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=h_cnt+48;
__delay_us(75); /* delay for write */
EN=0; /* disable write */
//DISPLAY TENS COUNT
RGSL=1; /* data register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=t_cnt+48;
__delay_us(75); /* delay for write */
EN=0; /* disable write */
//DISPLAY ONES COUNT
RGSL=1; /* data register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=o_cnt+48;
__delay_us(75); /* delay for write */
EN=0; /* disable write */
//LEFT SHIFT
RGSL=0; /* command register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=0X10; /* move command to LCD port */
__delay_us(75); /* delay for write */
EN=0; /* disable write */
//LEFT SHIFT
RGSL=0; /* command register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=0X10; /* move command to LCD port */
__delay_us(75); /* delay for write */
EN=0; /* disable write */
//LEFT SHIFT
RGSL=0; /* command register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=0X10; /* move command to LCD port */
__delay_us(75); /* delay for write */
EN=0; /* disable write */
}
}
}
void LCD_INIT(void)
{
TRISC=0x00; /* set PORTC pins as output */
TRISD=0x00; /* set PORTD pins as output */
__delay_ms(50);
LCD_COMM(0X30); /* 8-bit single line display selection */
__delay_ms(50);
LCD_COMM(0X38); /* 8-bit two line display selection */
LCD_COMM(0X0C); /* display on cursor off */
LCD_COMM(0X06); /* auto-address increment */
LCD_COMM(0X01); /* clear display */
}
void LCD_COMM(char COMM)
{
RGSL=0; /* command register select */
RW=0; /* register write select */
EN=1; /* write enable ie,H->L */
PORTD=COMM; /* move command to LCD port */
__delay_ms(50); /* delay for write */
EN=0; /* disable write */
}
The code works,however misses steps whenever the motor speed goes up a bit,which,i guess is to be expected from the LCD display routines.
That's the problem.The project is demonstration purpose,which is why i need the display(at least up to hundred counts)
and I'm a complete beginner with LCD's so i had no idea thr was any way to display wasting lesser machine cycles.
WHAT I ASK,is if the code can be further manipulated (specially the display part) as to not miss encoder steps at higher rpm's?
NOTE: I HAVE IGNORED INVALID STATES FOR NOW,DESCRIBING THEM AS 0 COUNT IN THE TABLE