Tachometer

General discussion on mikroPascal.
Author
Message
jomref
Posts: 8
Joined: 25 Feb 2007 19:17

Tachometer

#46 Post by jomref » 25 Feb 2007 19:29

I am new to MiC programming and after some tries with assembler programming i turned to MikroBasic and the Easy4. I am experimenting with a Smith triggered Hall effect sensor and using the example program (same as the one posted in Pascal). But I have at least one problem. My PiC is a 16F877A that runs at 8 MHz. The problem is that I need a Tacho that runns from 500 Rpm to 10000. The problem is that the CCPR2 (H and L) turns around at 1/30 sec which makes at RPM slower than 1830 a problem (Thus the timeperiod between signals get bigger than 1/30 sec). Can anyone give me a tip on how to encounter this problem.

Could a solotion be - as the CCPRT takes time from TMR1 (16bit) - use a prescale on TMR1. Is this possible.

Thanks in advance
Joachim
Sweden

FRM
Posts: 381
Joined: 20 May 2005 18:58
Location: UK

#47 Post by FRM » 25 Feb 2007 20:51

Yep, you can use a pre-scalar, but that'll proportionately reduce the resolution at higher speeds...Better to count & sum the CCP timer overflows and add the CCP captured value when the trigger occurs. You can capture an extremely long period provided you use appropriate accumulator variable(s)/pre-scalar value. You probably also realise that you can configure the CCP module to capture every 1/4/16th rising/falling edge.

If you are after precision, then you'll also have to take into account the interrupt latency, and use a compensated timer reload value within the interrupt routine.
You can use a combination of pre-scalar values/1..16th edge counts to get maximum resolution for both high and low speeds, with change over hysteresis in your code.

Another (simpler?) way is to use an external input that increments a timer configured as a counter each time your schitt trigger operates, which you sample at precise time intervals, but this obviously has limited resolution as the speed falls.

jomref
Posts: 8
Joined: 25 Feb 2007 19:17

Okey

#48 Post by jomref » 26 Feb 2007 07:09

I am not interested in precision but at least accurancy at a lower speed. My setup didnt display speeds under 1830 RPM (Longer periods than 1/30s) U said ; but that'll proportionately reduce the resolution at higher speeds. I thougt the prescaler makes the timers "tick" at a slower resolution.

Count and sum the CCP timer overflows should be one way of taking care of signals longer than 1/30 s (2x10^6/2^16). How does one capture the overflow of the TMR1.

Note that I am using the MikroE example program called Tachometer.

FRM
Posts: 381
Joined: 20 May 2005 18:58
Location: UK

Re: Okey

#49 Post by FRM » 26 Feb 2007 09:12

jomref wrote:U said ; but that'll proportionately reduce the resolution at higher speeds. I thougt the prescaler makes the timers "tick" at a slower resolution.
My answer is still qualified. Yes, at HIGHER speeds, you have less 'ticks' in your accumulator - this is referenced to resolution of measurement...not at LOWER speeds. As you say, you are not interested in accuracy - therefore these comments are now not valid. If you were concerned with 0.01Hz or better resolution then the pre-scaled timer is of concern, especially at lower mclock speeds.
jomref wrote: Count and sum the CCP timer overflows should be one way of taking care of signals longer than 1/30 s (2x10^6/2^16). How does one capture the overflow of the TMR1.
The same way as you capture the CCP timer snapshot, setup an interrupt for the same timer but for overflow, accumulate each time this occurs 2^16 - 1.

antony1925
Posts: 18
Joined: 20 Nov 2011 08:54

Re: Tachometer Help pls

#50 Post by antony1925 » 22 Nov 2011 04:56

Hi,

I have been using the PASCAL code to try interface my 18f452 with 16Mhz clock in Mikroc language.

I have understood CCP2 technique to capture the period between rising edge and falling edge, but I am using a reed switch to count the number of pulses that come from the switch to calculate the RPM.

Reed switch is always HIGH, so i have set the capture to every falling edge i.e CCP2CON = 0x04; and get the time and get the other time for the rising edge i.e. 0x05, so that it makes a single pulse train.

sorry i was unable to make a perfect one but i have explained what it looks like.

|'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''| |''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''|

<-rising edge when reed switch doesnot make contact-><-when in contact 0V---><-when its open returns back to 5v---->

Therefore I have written my code in this way, but I have a problem understanding how to calculate the RPM from the rotation period.

Can anyone explain how in the below code 60000000 came from, I mean how is this calculated for 4Mhz and how can I calculate for a 16MHZ clock.
RPM := 60000000 div R_Period ; //Calculate RPM (period is in clock cycles this turns it into revs/min)
//Conversion value valid for a 4 Mhz oscillator frequency ONLY
My code in MikroC

Code: Select all

unsigned double Rpm = 0;
unsigned float Rot_time = 0;     // rot_PH + rot_PL
unsigned float Pulse_HSL;   // holding falling edge time for start of timing sequence
unsigned float Pulse_HSH;
unsigned float Pulse_EL;   // rising edge for end time sequence
unsigned float Pulse_EH;
unsigned float Rot_PH = 0;
unsigned float Rot_PL = 0;
void main()
{
      //Soft_Uart_Init(PORTC,7,6,57600,0);
      delay_ms(500);
      TRISD= 0;  //Set all PORTD for output
      PORTD= 0;
      TRISC= 0x02;  //RC1 as input for CCP2
      
      INTCON  = 0;  //Disable all Interrupts for initialization of other registers
      T3CON   = 0;  //0000 0000  was $C0 Sets Timer1 as source clock for CCP1 and CCP2 leaves timer3 off
      CCP2CON = 0x04; // set for every faling edge, 05 every rising edge capture
      //CCP2CON = 0x06;  //set for 4th rising edge, $07 Initially Set CCP2 for 16th Rising Edge Capture
      T1CON   = 0x01;  //set for 8 bit time read, prescaler of 1 and turn timer 1 on
      //T1CON = 0x81; // set for 16bit read, prescaler 1 and timer1on
      TMR1L   = 0x00; //zero timer registers
      TMR1H   = 0x00;
      
while(1)
{

      if(PIR2.CCP2IF == 0 && CCP2CON = 0x04) // if flag is set and pulse is trigerred
      {
        Rot_time = (Rot_PH<<8)|Rot_PL; //combining both hi and low byte of rotation period
        Rpm =


}
}
void interrupt()
{
      INTCON.GIE =0; // clearing GIE to prevent any other interrupts while handling this one
      
      if(PIR2.CCP2IF == 1)
      {
        switch(CCP2CON)
        {
          case 0x04: // start time of the sequence i.e. falling edge and gets start time
          Pulse_HSL = CCPR2L; // capture pulse high start time
          Pulse_HSH = CCPR2H; // get captured time high byte
          CCP2CON = 0x05;
          PIR2.CCP2IF = 0; // reset the flag
          break;
          
          case 0x05: // end time sequence so timing sequence complete, calculate time intervals
          Pulse_EL = CCPR2L; // get time of the rising edge
          Pulse_EH = CCPR2H;
          Rot_PL = Pulse_EL - Pulse_HSL; // rotation time = Pulse time HI + pulse time LOW
          //if(STATUS == 0){ Pulse_EH = Pulse_EH - 1; }
          Rot_PH = Pulse_EH - Pulse_HSH;
          CCP2CON = 0x04; // set start next timing sequence for falling edge.
          PIR2.CCP2IF = 0;
          break;
          
          default:  rpm =0;
         } // switch
       }  // if
}   // interrupt
I just need to understand whether my idea on taking times while there is an interruprt flag set when the switch goes into falling edge is correct or not and to find the RPM.

Best Regards
Antony

Charlie
Posts: 2744
Joined: 01 Dec 2004 22:29

Re: Tachometer

#51 Post by Charlie » 22 Nov 2011 11:33


Can anyone explain how in the below code 60000000 came from

That number is the number of micro seconds in a minute. Here is a lick to some code that really works well.
http://www.mikroe.com/forum/viewtopic.p ... &hilit=ccp
Also If I were you I would use a Hall effect switch instead of a reed switch. the reed switch is prone to bounce which will give you false readings.
Regards Charlie M.

antony1925
Posts: 18
Joined: 20 Nov 2011 08:54

Re: Tachometer

#52 Post by antony1925 » 22 Nov 2011 11:50

Thank you Charlie..

I would really take ur advice to use hall effect sensor instead of reed switch and give it a try.

Do you have any idea about the logic that I have explained in my program? or is it correct by any chance.

I would need to test it to check it but i just want to make sure if U have any idea about the code and will it work with a reed switch.

Cheers
Antony

Charlie
Posts: 2744
Joined: 01 Dec 2004 22:29

Re: Tachometer

#53 Post by Charlie » 22 Nov 2011 12:09


Can anyone explain how in the below code 60000000 came from, I mean how is this calculated for 4Mhz and how can I calculate for a 16MHZ clock.
RPM := 60000000 div R_Period ; //Calculate RPM (period is in clock cycles this turns it into revs/min)
Timer1 runs at 1/4 osc speed so if you are using a 16mhz xtal then timer runs at 4 mhz. that is way too fast for what you are doing. 4 mhz is more practical and gives you a balance from some what low rpm ~229 and high rpm some where around 58000 rpm. Basically in the formula above 60000000 is how many micro seconds are in a minute. the period is the time between pulses in Us. So if you divide 60000000/ period then the answer is pulses/min.... I think that is correct. if some one else has more to add please do so.
Regards Charlie M.

antony1925
Posts: 18
Joined: 20 Nov 2011 08:54

Re: Tachometer

#54 Post by antony1925 » 22 Nov 2011 12:41

Hi charlie,

I am using this program to calculate the cadence (in Bicycles). So i stick these reed switches on the crank arm and attach a magnet on the spoke of the rear wheel to get each pulse whenever reed switch comes in contact, saying that each time I get a pulse I count it as 1 rotation and so on.

From these rotations I calculate the RPM i.e the cadence of the bicycle.

Will my logic obtain correct results in finding the RPM through the program that I have attached?

Or should I work on any other parts of the code?

Please help me and I really appreciate for your replies.
Thank you

cheers

Charlie
Posts: 2744
Joined: 01 Dec 2004 22:29

Re: Tachometer

#55 Post by Charlie » 22 Nov 2011 12:59

well first I would use a hall sensor instead of a reed switch. next thing is you are going to have to use a lower freq. osc. Pm me when you get time and I will see if I can help and little more.
Regards Charlie M.

antony1925
Posts: 18
Joined: 20 Nov 2011 08:54

Re: Tachometer

#56 Post by antony1925 » 02 Dec 2011 02:31

Hi People,
R_Period := 00;
R_period := Word(Rot_P_H shl 8) OR Rot_P_L; //combined hi and low byte of rotation period into word
RPM := 120000000 div R_Period ; //Calculate RPM (period is in usec this turns it into revs/min) // 6.25 lbs auto gasoline/gallon US 100 LL Aviation fuel maybe 5.97 lbs
Display_RPM(RPM); //Displays Operational Da
When I run my hardware using this code I do not get the RPM, there are values ln thousands i.e. 65534.99, 3024.99 and so on are displaying on the LCD. I used a 8Mhz crystal so i changed into 12e7 in the program eventhough I use a 4mhz i did not get the exact RPM.

Can anyone help me whether i am on the right track in understanding or is there any other procedure I can work this out.

I use PIC18f452 and 8hz crystal.

Regards
Antony

piort
Posts: 1379
Joined: 28 Dec 2005 16:42
Location: Laval,Québec,Canada,Earth... :-)
Contact:

Re: Tachometer

#57 Post by piort » 02 Dec 2011 04:33

hi,
its exist many way to get RPM... In the past , i had work on a project where i need to read the rpm of 2 different part of the machine. The approach i had choice is a bit different but work fine for my purpose.
the main principle is : CCP run like a timer.... the number in CCPR is the number of cycle between 2 pulse. If the value become higher the 16 bit, he restart at 0. So What i do in interrupt is run a timer in same time . When the timer overflow, that increase a variable. When the CCP flag come, i add the CPPR value to the variable value. So in this way, i can use the max frequency of my MCU.
To calculate the RPM i use the formula : 60 / ((CPPR value * (timer overflow value * 65535)) * TCY in second..
nothing is better than a example ;-) Code come from project with a 18f2620 in MP Pro

Code: Select all

const
tcy : real = 0.000000125 ;   //  1 / (fosc/4) = TCY in second

var
moteur                 : dword;
RPM_moteur          : real;
ovrflw                  : integer;
capture1              : word ; absolute 0xFBE;  // CPPR value for a 18f2620
tmr1_value           : word; absolute 0xFCE;
cap1_f                 : sbit at pir1.ccp1if;
cap1_e                : sbit at pie1.ccp1ie;

procedure interrupt;
begin
if cap1_f = 1 then   // cpp1 pulse in flag
  begin
  moteur := capture1 + (ovrflw * 65535);   // add at CCPR the value come from tmr overflow
  ovrflw := 0;        // reset overflow flag
  pie1.tmr1ie :=0;
  tmr1_value := 0 ;   // reset tmr value
  pie1.tmr1ie :=1;
  cap1_f := 0;     // clear flag
  end;

  if pir1.TMR1IF = 1 then   // if T1 overflow
  begin
  ovrflw := ovrflw + 1 ;     // inc overflow flag
  pir1.TMR1IF := 0;          // resert tmr flag
  end;
end;

// somewhere else in the code

 RPM_moteur := (60/(moteur * tcy)) ; // calculate RPM
 floattostr(rpm_moteur,tempostr); // convert real to string
 lcd_out(1,1,tempostr); // show RPM on LCD

Hope that hlp a bit ;-)

Post Reply

Return to “mikroPascal General”