joeylee
Newbie level 4
hi all,
can someone help me on how to write program for rotary encoder to count speed.
so far, i only manage to capture the high value of the rotary encoder using interrupt but the value stay there.
can someone please help me, how to set the value to zero after 1 second so i can keep loop to count the speed every 1 second.
im using pic18f452 with crystal 4 MHz.
here is my code,
#include <p18f452.h>
#include <delays.h>
#include <adc.h>
#include <capture.h>
#include <timers.h>
#include <stdlib.h>
#include <math.h>
#pragma config OSC = XT
#pragma config WDT = OFF
#pragma config LVP = OFF
#define LED_ON PORTCbits.RC4
#define LED2 PORTDbits.RD6
#define LED1 PORTDbits.RD5
#define LED3 PORTDbits.RD7
#define RW_PIN PORTDbits.RD1 /* PORT for RW */
#define RS_PIN PORTDbits.RD3 /* PORT for RS */
#define E_PIN PORTDbits.RD0 /* PORT for E */
#define DATA_PIN PORTB // data pins but only use PB0-PB3
#define CapRise 0b00000101;
#define CapFall 0b00000100;
//LCD FUNCTION
void lcd_print_char(unsigned int);
void lcd_print_string(char []);
void lcd_command(unsigned int);
void lcd_init(void);
/*===================================================================================================
||||| Declare IR SENSor Functions |||||
===================================================================================================*/
void Get_Distance(void);
/*===================================================================================================
||||| Declare Interupt Functions |||||
===================================================================================================*/
void isr_high(void);
void isr_low (void);
void init(void);
/*===================================================================================================
||||| String Messages |||||
===================================================================================================*/
char output[] = "Alarm Activated";
char output1[] = "Alert";
char output2[] = "Slow Down";
char output3[] = "Dangerous";
char output4[] = "Critical";
/*===================================================================================================
||||| Global Variables |||||
===================================================================================================*/
short sensor_flag=0;
int sensor=0;
char sensorASCII[5];
int counter = 0;
/*===================================================================================================
||||| Enable ISR Checking |||||
===================================================================================================*/
int i=0;
int value = 0;
char valueASCII[7];
char iASCII[7];
/*===================================================================================================
||||| Main Program |||||
===================================================================================================*/
void main(void)
{
TRISCbits.TRISC4=0; //set LED_ON as input
TRISDbits.TRISD5=0;
TRISDbits.TRISD6=0;
TRISDbits.TRISD7=0; //set BUTTON as output
TRISA=0Xff;
LED_ON=1; //to show power on
TRISB=0x00;
TRISDbits.TRISD0=0;
TRISDbits.TRISD1=0;
TRISDbits.TRISD3=0;
DATA_PIN=0x00;
RW_PIN=0;
RS_PIN=0;
E_PIN=0;
Delay10KTCYx(10);
lcd_init();
init();
while(1)
{
OpenADC(ADC_FOSC_4 & ADC_RIGHT_JUST & ADC_8ANA_0REF, ADC_CH0 & ADC_INT_OFF);
Delay10TCYx(5);
ConvertADC (); // Start conversion
while (BusyADC()); // Wait for completion
sensor = ReadADC();
CloseADC();
itoa(sensor , sensorASCII);
lcd_command(0b11000000);
lcd_print_string(sensorASCII);
Get_Distance(); //Check for deactivation code
}
}
/*===================================================================================================
||||| LCD Initialization |||||
===================================================================================================*/
void lcd_init(void)
{
E_PIN = 0;
RS_PIN = 0;
RW_PIN = 0;
lcd_command(0b00100000);
lcd_command(0b00101000);
lcd_command(0b00001100);
lcd_command(0b00000001);
lcd_command(0b00000010);
}
/*===================================================================================================
||||| LCD Print Character with 4-bits interface |||||
===================================================================================================*/
void lcd_print_char(unsigned int character)
{
DATA_PIN=character >> 4;
RS_PIN = 1;
E_PIN = 1;
E_PIN = 0;
RS_PIN = 0;
DATA_PIN=character & 0x0f;
RS_PIN = 1;
E_PIN = 1;
E_PIN = 0;
RS_PIN = 0;
}
/*===================================================================================================
||||| LCD Print String |||||
===================================================================================================*/
void lcd_print_string(char string[])
{
int count =0;
while(string[count] != '\0')
{
lcd_print_char(string[count]);
count++;
}
}
/*===================================================================================================
||||| LCD Instruction with 4-bits interface |||||
===================================================================================================*/
void lcd_command(unsigned int lcd_command)
{
DATA_PIN=lcd_command >> 4;
E_PIN = 1;
E_PIN = 0;
DATA_PIN=lcd_command &0x0f;
E_PIN = 1;
E_PIN = 0;
Delay1KTCYx(10);
}
/*===================================================================================================
||||| Keypad Get Inputs |||||
===================================================================================================*/
void Get_Distance(void)
{
LED2=~2;
ultoa(value, valueASCII);
lcd_command(0b10000000);
lcd_print_string(valueASCII);
}
// interrupt setup
#pragma code high_vector=0x08
void high_vector (void)
{
_asm GOTO isr_high _endasm
}
#pragma code low_vector=0x18
void low_vector (void)
{
_asm GOTO isr_low _endasm
}
#pragma code
#pragma interrupt isr_high
void isr_high (void)
{
if(!PIR1bits.TMR1IF)
{
//TMR0 Overflow ISR
counter++;//Increment Over Flow Counter
value +=1;
PIR1bits.CCP1IF = 0; // clear capture flag bit
}
else
{
value=0;
}
}
#pragma interruptlow isr_low
void isr_low(void)
{
// unused
}
void init(void)
{
TRISC = 0x04; // RC2 CCP1 pin = input
CCP1CON = CapRise; // capture on rising edge
// interrupt setup
PIR1bits.CCP1IF = 0; // clear capture flag bit
IPR1bits.CCP1IP = 1; // CCP1 int is high priority
PIE1bits.CCP1IE = 1; // enable CCP1 interrupt
RCONbits.IPEN = 1; // enable priority levels on interrupts
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
PIE1bits.TMR1IE = 1;
PIR1bits.TMR1IF = 0;
INTCON = 0b11100000; // global & peripheral ints enabled
}
can someone help me on how to write program for rotary encoder to count speed.
so far, i only manage to capture the high value of the rotary encoder using interrupt but the value stay there.
can someone please help me, how to set the value to zero after 1 second so i can keep loop to count the speed every 1 second.
im using pic18f452 with crystal 4 MHz.
here is my code,
#include <p18f452.h>
#include <delays.h>
#include <adc.h>
#include <capture.h>
#include <timers.h>
#include <stdlib.h>
#include <math.h>
#pragma config OSC = XT
#pragma config WDT = OFF
#pragma config LVP = OFF
#define LED_ON PORTCbits.RC4
#define LED2 PORTDbits.RD6
#define LED1 PORTDbits.RD5
#define LED3 PORTDbits.RD7
#define RW_PIN PORTDbits.RD1 /* PORT for RW */
#define RS_PIN PORTDbits.RD3 /* PORT for RS */
#define E_PIN PORTDbits.RD0 /* PORT for E */
#define DATA_PIN PORTB // data pins but only use PB0-PB3
#define CapRise 0b00000101;
#define CapFall 0b00000100;
//LCD FUNCTION
void lcd_print_char(unsigned int);
void lcd_print_string(char []);
void lcd_command(unsigned int);
void lcd_init(void);
/*===================================================================================================
||||| Declare IR SENSor Functions |||||
===================================================================================================*/
void Get_Distance(void);
/*===================================================================================================
||||| Declare Interupt Functions |||||
===================================================================================================*/
void isr_high(void);
void isr_low (void);
void init(void);
/*===================================================================================================
||||| String Messages |||||
===================================================================================================*/
char output[] = "Alarm Activated";
char output1[] = "Alert";
char output2[] = "Slow Down";
char output3[] = "Dangerous";
char output4[] = "Critical";
/*===================================================================================================
||||| Global Variables |||||
===================================================================================================*/
short sensor_flag=0;
int sensor=0;
char sensorASCII[5];
int counter = 0;
/*===================================================================================================
||||| Enable ISR Checking |||||
===================================================================================================*/
int i=0;
int value = 0;
char valueASCII[7];
char iASCII[7];
/*===================================================================================================
||||| Main Program |||||
===================================================================================================*/
void main(void)
{
TRISCbits.TRISC4=0; //set LED_ON as input
TRISDbits.TRISD5=0;
TRISDbits.TRISD6=0;
TRISDbits.TRISD7=0; //set BUTTON as output
TRISA=0Xff;
LED_ON=1; //to show power on
TRISB=0x00;
TRISDbits.TRISD0=0;
TRISDbits.TRISD1=0;
TRISDbits.TRISD3=0;
DATA_PIN=0x00;
RW_PIN=0;
RS_PIN=0;
E_PIN=0;
Delay10KTCYx(10);
lcd_init();
init();
while(1)
{
OpenADC(ADC_FOSC_4 & ADC_RIGHT_JUST & ADC_8ANA_0REF, ADC_CH0 & ADC_INT_OFF);
Delay10TCYx(5);
ConvertADC (); // Start conversion
while (BusyADC()); // Wait for completion
sensor = ReadADC();
CloseADC();
itoa(sensor , sensorASCII);
lcd_command(0b11000000);
lcd_print_string(sensorASCII);
Get_Distance(); //Check for deactivation code
}
}
/*===================================================================================================
||||| LCD Initialization |||||
===================================================================================================*/
void lcd_init(void)
{
E_PIN = 0;
RS_PIN = 0;
RW_PIN = 0;
lcd_command(0b00100000);
lcd_command(0b00101000);
lcd_command(0b00001100);
lcd_command(0b00000001);
lcd_command(0b00000010);
}
/*===================================================================================================
||||| LCD Print Character with 4-bits interface |||||
===================================================================================================*/
void lcd_print_char(unsigned int character)
{
DATA_PIN=character >> 4;
RS_PIN = 1;
E_PIN = 1;
E_PIN = 0;
RS_PIN = 0;
DATA_PIN=character & 0x0f;
RS_PIN = 1;
E_PIN = 1;
E_PIN = 0;
RS_PIN = 0;
}
/*===================================================================================================
||||| LCD Print String |||||
===================================================================================================*/
void lcd_print_string(char string[])
{
int count =0;
while(string[count] != '\0')
{
lcd_print_char(string[count]);
count++;
}
}
/*===================================================================================================
||||| LCD Instruction with 4-bits interface |||||
===================================================================================================*/
void lcd_command(unsigned int lcd_command)
{
DATA_PIN=lcd_command >> 4;
E_PIN = 1;
E_PIN = 0;
DATA_PIN=lcd_command &0x0f;
E_PIN = 1;
E_PIN = 0;
Delay1KTCYx(10);
}
/*===================================================================================================
||||| Keypad Get Inputs |||||
===================================================================================================*/
void Get_Distance(void)
{
LED2=~2;
ultoa(value, valueASCII);
lcd_command(0b10000000);
lcd_print_string(valueASCII);
}
// interrupt setup
#pragma code high_vector=0x08
void high_vector (void)
{
_asm GOTO isr_high _endasm
}
#pragma code low_vector=0x18
void low_vector (void)
{
_asm GOTO isr_low _endasm
}
#pragma code
#pragma interrupt isr_high
void isr_high (void)
{
if(!PIR1bits.TMR1IF)
{
//TMR0 Overflow ISR
counter++;//Increment Over Flow Counter
value +=1;
PIR1bits.CCP1IF = 0; // clear capture flag bit
}
else
{
value=0;
}
}
#pragma interruptlow isr_low
void isr_low(void)
{
// unused
}
void init(void)
{
TRISC = 0x04; // RC2 CCP1 pin = input
CCP1CON = CapRise; // capture on rising edge
// interrupt setup
PIR1bits.CCP1IF = 0; // clear capture flag bit
IPR1bits.CCP1IP = 1; // CCP1 int is high priority
PIE1bits.CCP1IE = 1; // enable CCP1 interrupt
RCONbits.IPEN = 1; // enable priority levels on interrupts
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
PIE1bits.TMR1IE = 1;
PIR1bits.TMR1IF = 0;
INTCON = 0b11100000; // global & peripheral ints enabled
}