CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

QEI Velocity measurement with 18F4431

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
psicko275



Joined: 21 Mar 2013
Posts: 12

View user's profile Send private message

QEI Velocity measurement with 18F4431
PostPosted: Tue Apr 02, 2013 10:49 am     Reply with quote

Hi I am new in the forum, thanks for read this post!

I'm working with PIC18F4431 to read the velocity of CD motors with a encoder of 1200 PPR (Pulses per Revolution), I have read the NOTE: AN899 Brushless DC Motor Control Using PIC18FXX31 MCUs, and I find the correct form to read the velocity from counts of timer5 but don't from register velocity in CCS:
Code:
count=qei_get_count(QEI_GET_VELOCITY_COUNT);


If I measure the speed from the timer 5 this works well but when the rotor stops the velocity have a value different to zero.

so this my code:

Code:

#include <main_slave.h>
#byte CAP1BUFH = 0xF69
#byte CAP1BUFL = 0xF68
#byte CAP1CON = 0xF63
#bit  CAP1REN = CAP1CON.6
#byte PIR3 = 0xFA4
#bit  IC1IF = PIR3.1
float cte_velocity_rps = 0, cte_velocity_rpm=0;
int16 ad=0, count=0;
int32 INSTRUCTION_CYCLE = 5000000;
int16 ENCODER_PPR = 1200;
float RPM_CONSTANT_QEI = 0;

#int_IC1
/*
   Velocity capture interrupt
*/
void IC1_isr()
{
   count=qei_get_count(QEI_GET_VELOCITY_COUNT);
   ad=get_timer5();
//!   RPM_CONSTANT_QEI =cte_velocity_rps/ad ;      //In RPS revolutions per second, This works fine except when the rotor is stopped.
//!   RPM_CONSTANT_QEI =cte_velocity_rpm/ad ;      //In RPM revolutions per minute, This works fine except when the rotor is stopped.
   RPM_CONSTANT_QEI = 1953.125/count;                //this value obtain of the equation 5 in AN899 and I can't read correctly the velocity
// RPM=((Operating Frequency/4) / (PPR x Velocity Update Rate x Pulse Reduction Ratio x Timer5 Prescale x VELR<H:L>)) x 60
   set_timer5(0);
   qei_set_count(0);

}

void main()
{
   /*setup QEI*/
   setup_qei(QEI_MODE_X4_RESET_ON_MATCH | QEI_VELOCITY_MODE_ENABLED | QEI_VELOCITY_PULSE_DIV_4 ,QEI_FILTER_ENABLE_QEB | QEI_FILTER_ENABLE_QEA, 2400);
//!   setup_qei(QEI_MODE_X4_RESET_ON_MATCH, QEI_FILTER_ENABLE_QEB | QEI_FILTER_ENABLE_QEA, 2249);
   SETUP_TIMER_5(T5_INTERNAL | T5_DIV_BY_8);   
//!   enable_interrupts(INT_TIMER5);
   enable_interrupts(INT_IC1);
   enable_interrupts(GLOBAL);

cte_velocity_rps = 625000/ENCODER_PPR;    //cte_rps = (Operating Frequency/4) / (Timer5 Prescale x PPR)
cte_velocity_rpm = cte_velocity_rps*60;
   while(true)
   {
      output_toggle(LED);
   }  /*End to while(true)*/

}  /*End to main(void)*/



main_slave.h

Code:

#include <18F4431.h>
#device adc=10
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=20M)

#define LED PIN_C0
#define DELAY 10


I send the value RPM_CONSTANT_QEI to SPI communication, I don't put this code to simplify the question but if necessary I'llt.

Thanks for read, any ideas?
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue Apr 02, 2013 12:25 pm     Reply with quote

what "works" ????
you never call the result of your QEI function in MAIN after setup
all i see is a program that flashes a led so often it looks like its always on.

also including a floating point DIVISION op in an ISR is a HUGE mistake.

you understand this can be done without a float, outside the ISR, right ?
psicko275



Joined: 21 Mar 2013
Posts: 12

View user's profile Send private message

PostPosted: Tue Apr 02, 2013 1:59 pm     Reply with quote

thanks for answer me.
asmboy wrote:
what "works" ????
you never call the result of your QEI function in MAIN after setup
all i see is a program that flashes a led so often it looks like its always on.

also including a floating point DIVISION op in an ISR is a HUGE mistake.

you understand this can be done without a float, outside the ISR, right ?


I say that the variable RPM_CONSTANT_QEI I send to via SPI:

Quote:
I send the value RPM_CONSTANT_QEI to SPI communication, I don't put this code to simplify the question but if necessary I'llt.


So this float DIVISION in the ISR works! and I'm no expert sorry.

How can I do outside the ISR?
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue Apr 02, 2013 2:11 pm     Reply with quote

Store count in a circular buffer, of magic size, and harvest the values from it, to the MAIN using a second pointer var.

Code:

 unsigned int16 ad[16],count[16];

 unsigned int8 incp=0,outcp=0;

void IC1_isr()
{
   count[incp]=qei_get_count(QEI_GET_VELOCITY_COUNT);
   ad[(incp++)] =get_timer5();
    incp = incp%16; // index 0 to 15
   set_timer5(0);
   qei_set_count(0);

}


Use OUTCP to decide which items you last pulled from the buffer this creates.
Then do your FP math in MAIN section.

ALSO for BEST resolution you may need to reverse when you load
count[] and ad[] based on which Var has the higher (nominal) received values - as it might be timer5...
psicko275



Joined: 21 Mar 2013
Posts: 12

View user's profile Send private message

PostPosted: Thu Apr 04, 2013 7:07 am     Reply with quote

Thanks for the FP advice asmboy.
You know how to use the function to get the correct speed?
Code:
qei_get_count(QEI_GET_VELOCITY_COUNT);
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Apr 04, 2013 11:54 am     Reply with quote

honestly have never used it to determine speed.
have only used it to count encoder clicks and direction with user quad digital "pot".
psicko275



Joined: 21 Mar 2013
Posts: 12

View user's profile Send private message

PostPosted: Thu Apr 04, 2013 3:28 pm     Reply with quote

thanks for help me!
asmboy wrote:
honestly have never used it to determine speed.
have only used it to count encoder clicks and direction with user quad digital "pot".


I'm waiting for more answers!
psicko275



Joined: 21 Mar 2013
Posts: 12

View user's profile Send private message

PostPosted: Thu Apr 11, 2013 6:39 am     Reply with quote

Anyone? Shocked
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Apr 11, 2013 7:39 am     Reply with quote

why not see the code in the other thread ???

and go from there ??

http://www.ccsinfo.com/forum/viewtopic.php?t=43199
psicko275



Joined: 21 Mar 2013
Posts: 12

View user's profile Send private message

PostPosted: Mon Apr 15, 2013 12:19 pm     Reply with quote

asmboy wrote:
why not see the code in the other thread ???

and go from there ??

http://www.ccsinfo.com/forum/viewtopic.php?t=43199


Yes in this page I write but anyone answer me my doubt.

thanks!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group