Tachometer

General discussion on mikroPascal.
Author
Message
ghspirit
Posts: 22
Joined: 07 Oct 2004 10:25

tach problem in MB

#31 Post by ghspirit » 03 Oct 2005 23:15

Hello,

Thanks to your fast reply but in my code that i have compile and test with a 16f876 4 mhz i put "8)" in R_Period = Word(Rot_P_H << HERE OR Rot_P_L ! SO, is not the problem! But Has you see, in a 16f876 i don't have "T3CON" SO, in your code i have simple erase this line "'T3CON = $00 '0000 0000 was $C0 Sets Timer1 as source clock for CCP1 and CCP2 leaves timer3 off" with a " ' "! I think it's a problem but with what i must replace T3CON = $00 in my 16f876???


Sub Procedure Initialize_Timer_CCP

INTCON = $00 'Disable all Interrupts for initialization of other registers
'T3CON = $00 '0000 0000 was $C0 Sets Timer1 as source clock for CCP1 and CCP2 leaves timer3 off
CCP2CON = $06 'set for 4th rising edge, $07 Initially Set CCP2 for 16th Rising Edge Capture
T1CON = $01 'set for 8 bit time read, prescaler of 1 and turn timer 1 on
TMR1L = $00 'zero timer registers
TMR1H = $00

End Sub

Best Regards

ghspirit
Posts: 22
Joined: 07 Oct 2004 10:25

When i say 8) it always put a smile but i put 8 and )

#32 Post by ghspirit » 03 Oct 2005 23:16

When i say 8) it always put a smile but i put 8 and ) like you say in your post!

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Tach

#33 Post by Rotary_Ed » 03 Oct 2005 23:57

Ok, I thought the "8)" might be there but was not certain. Unfortunately, I have no experience with any of the chips but the 18F452, so unable to suggest what you might do with your chip.

I presume that the pulse train your are feeding your chip is varying and not just stuck at at value that would give your the 5580 rpm?

Wish I could assist more, good luck.
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

ghspirit
Posts: 22
Joined: 07 Oct 2004 10:25

It's works in MB ;-))

#34 Post by ghspirit » 04 Oct 2005 15:23

Hello,

I found the problem, it's in the procedure "Sub Procedure ccp2_RPM(Dim Rot_P_H as byte,Dim Rot_P_L as byte)" I use "Rot_P_H" and "Rot_P_L" in PROCEDURE VARIABLE AND NOT IN GLOBAL VARIABLE!!! And the result never return and was always "0"!!!! So i put it in global variable and all work well!!!

To have just the time(µs or ms) of 1 pulse go on and go off! How can i have it??? I want just to know how many time(µs) the pulse are in High Logic? It's the TIME HI_LOGIC=word(Pulse_HSH <<8) OR Pulse_HSL ???
Best Regards,

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Logic High?

#35 Post by Rotary_Ed » 06 Oct 2005 01:12

Glad you found the problem with your code. The Tach_Acq unit was code to provide the time from rising edge of pulse to next rising edge of pulse. This is one revolution period for Tachometer RPM. To read only the high pulse is also possible. However, the code must be re written. There are changes required in the CCP2 module, the calculation of PW and in the setting of CCP2Con.

Here is the code modified to measure the duration of Pulse High (Logic High) of a pulse train. It will measure between 1 and 10 milliseconds (I have tested it for that interval, but it should work for larger values).

The key is you must set the CCP module to intercept on the rising edge and falling edge capturing the Timer value at each point. Then by math you find the duration of the pulse for logic High.

The LCD will display the logic high as xx.xx milliseconds without the decimal. So for example, display of 750 is 7.50 milliseconds.

Note: you must set the LCD initialization different than my code to one that works for your LCD hook up.

Here is the code. There is the Main program PW_High.ppas and one Unit PW_Acq_high.ppas. It is possible to combine the two into one program.

1st is Main program

Code: Select all

program PW_High;

//Program measures the logic High portion of a pulse train based on a pulse input and displays the PW in milliseconds
//NOTE: Interrupt Procedure is NOT  used as the CCP2 interrupt flag is set regardless
//of whether interrupt is enabled.  Since the CCP2IF is checked in the Main repeat loop, there is no
//need for the MP3 Interrup Procedure.

uses PW_Acq_High;  //Determines logic Hign period time based on Timer TMR1
               //Note this works for an 18F452 with a 4 Mhz crystal
                //MP3 Default Configuration  for 18F452 chip was used for chip configuration
               ////Note:  18F452 Chip is configured so that CCP2 is on pin RC1
               // rather than RB3  __CONFIG _CONFIG3H_OFF
               //Pulse train must be +5V (Pluse logic High) and 0 volts (Pulse Logic Low)

Procedure Initialize_LCD;   //This must be tailored for your particular LCD set up
  begin

       LCD8_Config(PORTC,PORTD,6,4,5,7,6,5,4,3,2,1,0); //RS,EN,RW  Data Use in Real Fuel board Initialze LCD through PORTs
       LCD8_Cmd(Lcd_Clear);//Clear LCD display
       LCD8_Cmd(Lcd_Cursor_Off);//Turn visible cursor off

  end;

Procedure Initialize_Ports;
  begin

      TRISD:= $00;  //Set all PORTD for output
      PORTD:= $00;
      TRISC:= $02;  //   0000 0010  Set  bit RC1 for CCP2 input, RC6,4,5(Rs/En/RW) LCD control Output

  end;

Procedure Initialize_Timer_CCP;
   begin

      INTCON := $00;  //Disable all Interrupts for initialization of other registers
      T3CON  := $00;  //0000 0000  was $C0 Sets Timer1 as source clock for CCP1 and CCP2 leaves timer3 off
      CCP2CON:= $05;  //set for 1th rising edge
      T1CON  := $01;  //set for 8 bit time read, prescaler of 1 and turn timer 1 on
      TMR1L  := $00; //zero timer registers
      TMR1H  := $00;

   end;


Procedure Display_PW(PW:word);
    var Txt: array[6] of char;
        Txtstr: array[12] of char;
    begin
         Txt := '  '; //Intialize Txt
         TxtStr := ' MP3 PW High';
         LCD8_OUT(1,1,Txtstr);
          TxtStr := 'X.XX msec';   //Displayed when Pulse train to CCP2 is active
         LCD8_Out(2,8,Txtstr);
         Wordtostr(PW,Txt);
         LCD8_OUT(2,1,Txt);

    end;

Procedure CCP2_Call;   //Calls CCP2_PW to get pulse interval of rotation period then calculates and displays PW
     Var
           PW_L  :byte; //Bytes to hold pulse time information from Tach_Acq_High unit
           PW_H  :byte;
           PW :Word; //Holds PW Logic High time calculated

   Begin

           PW_L := 0;//Variables for Rotation Period Time
           PW_H := 0;
     If testbit(PIR2,CCP2IF) = 1   then //If CCP2 flag is set then pulse has triggered CCP2 module
      begin

         ccp2_PW( PW_H,PW_L); //Calls to Data_Acq unit for pulse measurements
            if (CCP2CON = $05) AND (CCP2IF = 0) then    //update viariable values and make calculation  after finished with entire timeing sequence
             begin

                  PW   := 00;
                  PW   := Word(PW_H shl 8) OR PW_L;//combined hi and low byted of High Pulse period into word
                  PW  := PW div 10;
                   //Calculate PW(period is in clock cycles this turns it into milliseconds)
                                          //Conversion value valid for a 4 Mhz oscillator frequency ONLY
                  Display_PW(PW); //Displays PW Data

              end; //If (CCP2CON =5 .....


     ClearBit(PIR2,CCP2IF);//Clear ccp2 Flag for next cycle
      end;

   end;

begin  //Main part of program
    Initialize_Ports;
    Initialize_LCD;
    Initialize_Timer_CCP;


    Repeat     //Loop forever calling CCP2_Call to determine rotation period and calculate PW

      CCP2_call;    //Call for Data and displayPW based on CCP2 module response to a pulse train

    until true = false;
end.

//Next is Unit 

unit PW_Acq_High;


implementation



Procedure ccp2_PW(Var PW_H,PW_L:byte);//CCP2_Fuel;

  //This procedure is to measure the period of a pulse train to pin RC2.
 //  

 // Note:  The procedure is set up to interrupt on the 1st rising edge of a pulse  CCPXCON := 05

 //****************************  Start of timing sequence *********************************************************
//                     <--- ->
// '   ''''''''''|       |'''''''''  ''|       |'''''''''''       
//            |.......|           |.......|                    
//                    1stRE     FE       RE
//                  start  Time   Stop Time

//****************************************************************************************************************



  //*********************************************************************
  //Note:  18F452 Chip is configured so that CCP2 is on pin RC1 rather than RB3  __CONFIG _CONFIG3H_OFF
  //*********************************************************************

 //The rising edge CCP2 capture set as CCP2Con := $05  Must also reset value in main pgrom in CCP2 Initialization procedure
 //and CCP2_Call Procedure (where If statement signifies end of timeing sequence)
  Var

	   Pulse_HSL  :byte; //Hold Rise Edge time for start of timing sequence
	   Pulse_HSH  :byte;

	   Pulse_LSL  :byte; //Hold Falling Edge time ( end of logic High)
	   Pulse_LSH  :byte;
     TPulse_EL  :byte; //temp variable for pulse High Logic (Low byte)
     TPulse_EH  :byte; //Temp variable for Pulse High Logic  (High byte);

begin          //Start measurement with pulse going low (falling), end measurement with pulse going high (rising)
  ClearBit(INTCON,GIE);                       //clear GIE to prevent further interupts while handling this one

	if TestBit(PIR2,CCP2IF) = 1 then            //Is it CCP2 Interrupt?
	    begin    //Yes, it is CCP2 Interrup.
         // The CASE section determines which code section processes the request, Start_Time, Fall_Edge or 2nd Rise_Edge

          case CCP2CON of   //Note: CCP2CON := $05 (  Rising edge)
          $05:  //This STARTS TIMING SEQUENCE, get start time of every  rising edge - Leave and wait for next falling ($04) Edge of pulse train
               //*******  Captures Start time of pulse sequence (Rising edge  *****************************************************=
                              begin

                  Pulse_HSL := CCPR2L;      //Get captured pulse high start time low byte     *******Change back to CCPR1L *****
                  Pulse_HSH := CCPR2H;       //Get captured time high byte

                  CCP2CON := $04;          //Set to capture next Falling edge
                  ClearBit(PIR2,CCP2IF);   //Reset to preclude False Interrupt

              end;
          $04:  //This detects the falling edge which is the end of the pulse logic HIGH
                    begin

                   Pulse_LSL	:= CCPR2L;  //Ge start time of low Logic zero = end of Logic High
                   Pulse_LSH	:= CCPR2H;
                   TPulse_EL:=Pulse_LSL;  //Hold time value
                   TPulse_EH:=Pulse_LSH;
                   
                   PW_L     := Pulse_LSL - Pulse_HSL;  //Calculate Pulse High  Time   low byte
                  IF TestBit(STATUS,C) = 0 then       //if Borrow required reduce high value of TPulse_H by 1
                     TPulse_EH := TPulse_EH - 1;
                   PW_H     := TPulse_EH - Pulse_HSH;  //Calculate Pulse High Time High byte
                        //ReSet for Rising Edge Capture on next entry into ISR


                  [b] CCP2CON := $05[/b];          //ReSet for Rising Edge Capture on next entry into this CCP2_PW Routine
                   ClearBit(PIR2,CCP2IF);   //Clear in case of false interrupt when changin mode
             end;


          end;//case

       end;  // end of IF Statement CCP2_Inj

   end;

end.
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

ghspirit
Posts: 22
Joined: 07 Oct 2004 10:25

Pulse timer OK but signal input problem with Tacho

#36 Post by ghspirit » 06 Oct 2005 16:26

Hello,

Thanks for your pulse timer!!! It work well but if i need to measure pulse of 10 µs or 150 ms period ON how can do it? My signal that i take is from an injector of the engine!SO, for one injection(2 engine revolutions) i have a big pulse and then 10 small pulse(pre-injection and injection)! So, my problem is to measure time between 2 raise of the big pulse to know the time for 2 revolutions engines! How can differenciate big pulse and small?

One way but is theory is to measure time of each pulse and when i have the biggest time i start the timer and wait to have another same pulse but i don't know if the time of big pulse change rapidely??? Do you have anothers ideas???

Best Regards

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Pulse signal

#37 Post by Rotary_Ed » 07 Oct 2005 22:48

It would help if you could describe your pulse train in more detail. A drawing would help.

I am surprised that you would need 10 usec resolution for a fuel injection system. I programmed one to read the injection pulse train for a Mazda Rotary engine. At 6000 rpm the period of revolution is 10 milliseconds, the injector on time varies between 1.5 milliseconds and 5 milliseconds depending on power being produced.

Most electronic fuel injectors will not function (open and close) if the PW is below 1.5 milliseconds.

It would help if you could describe your pulse train in more detail. A drawing would help.

Yes, if there is only one large (duration?) pulse per revolution then measuring all pulse durations and then based on the largest you could start your timing. However, when do you know it is the largest? Is the largest pulse always a specific duration?? or do you have to compare all pulses? There may be an easier way.

It would help if you could describe your pulse train in more detail. A drawing would help.
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

ghspirit
Posts: 22
Joined: 07 Oct 2004 10:25

How to generate pulse with different Freq/Period

#38 Post by ghspirit » 10 Oct 2005 19:33

Hello,

Thanks for you pulse high program, it resolve my problem! My signal is a signal that have all the time different Freqency but with Constant Period depending of the RPM! So, pulse high is very fine! I need know to translate my signal in different Period! So, how can i produce pulse when i want (not with a fixed freqency) and during a "X" period[ms] WITHOUT Interrupt because i need to use pulse high program and if i use interrupt it will corrupt the TIMER of the capture pwm mode, isnt it?

Simply i need to adapt the pulse high program to produce a pulse_out period depending of the pulse_in period without a fixed frequency because i make 1 pulse_out when i have 1 pulse_in! It's like i would like to make a pulse IN/OUT converter! Of course i take the period of the (n-1) pulse to calculate the time of my pulse_out period!

A function like pulse_out=(pulse n-1 _in period,% of the period,pin number)

If you can help me or give me idea how to make that it will be very nice!
Best Regards

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Pulse Signal

#39 Post by Rotary_Ed » 10 Oct 2005 20:52

I think I am beinging to understand what you want to do, but not certain on all aspects.

1st you do not have to use procedure interrupt. I have not found its implementation in MP3 to be of any value since you can not call a procedure from it. The CCP module will have its flag set when the trigger conditions are met even if the CCP module interrupt is NOT enabled. The flag CCPxIF will always be set when trigger conditions are met. That way- all you have to do is check the CCPxIF flag in your program to see if its set or not. That is what I do - you will notice there is no Procedure Interrupt used in my programs.

Here is a simply program that generates logic high pulses of abritary period - or you can simply generate one pulse as you choose. A more elegant solution would be to use one of the timers rather than the MP delay_MS/delay_us procedures. However, the Delay procedures are rather accurate - at least for the 4 Mhz oscillator.

Here is code that might give you some ideas. Depending on how many values you need to generate something this simple could work. In the mean time - I'll try to find some time to do something with the CCP PWM capability - need to refresh my knowledge.

Hope this helps.

Code: Select all

program PWM_Test;



var i, j : byte;
    ms   :word;
 Procedure XPeriod (Logic_High:word) ;

  begin  //Note MS3 Delay_MS(x) funtion will not take a variable as an argument - it must be a constant
         //Otherwise this would be much simpler
  
   case MS of
   1: begin
        PORTB.0 := 1;  //Turn on PW Logic High
        Delay_MS(1 );
        PORTB.0 := 0;  //Turn off PW Logic Low
        Delay_MS(1 );
      end;
    2: begin
        PORTB.0 := 1;  //Turn on PW Logic High
        Delay_MS(2 );  //Duration of logic High
        PORTB.0 := 0;  //Turn off PW Logic Low
        Delay_MS(10 );  //Duration of Logic Low (can be set to a different value to give a different frequency)
      end;
    5:begin
        PORTB.0 := 1;  //Turn on PW Logic High
        Delay_MS(5 );
        PORTB.0 := 0;  //Turn off PW Logic Low
        Delay_MS(10 );  //Note different Frequency

      end;
    10:begin
        PORTB.0 := 1;  //Turn on PW Logic High
        Delay_MS(10 );
        PORTB.0 := 0;  //Turn off PW Logic Low
        Delay_MS(5 );
      end;
    20:begin
        PORTB.0 := 1;  //Turn on PW Logic High
        Delay_MS(20 );
        PORTB.0 := 0;  //Turn off PW Logic Low
        Delay_MS(20 );
        end;
     end;//Case
   end;
   // Concept  1.  Turn on A pulse (send a port bit logic high
   //          2.  Start Timer
   //          3.  When timer reaches desired value
   //          4.  Turn off pulse (send port bit Logic Low
begin
    TRISB := $00; //Make PORTB output
    
    ms := 10;//Change value as desired.  Choice of value MUST match CASE conditions in procedure Xperiod

  Repeat
    Xperiod(MS);
  Until True = false;  //OR can use a for loop or use by itself for a single pulse
  
end.
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

ghspirit
Posts: 22
Joined: 07 Oct 2004 10:25

Vdelay_ms !!!! Is the solution!!!

#40 Post by ghspirit » 10 Oct 2005 21:26

Hello,

Thanks for your idea but in MB and in MP there is a function call Vdelay_ms (parameter) but mikro team say that is not accurate like delay_ms but i have find a solution to have a Vdelay accurate! What do you think of this:

To generate 12 ms i can use with a 4 Mhz clock (1 Cyc= 1/4000000 s) = > delay_Cyc(4) * 1000(µs to ms) * 12(number of ms)!!! The function is:

I have a precision of 1 µs i think because of delay_Cyc(4)!!!

Code: Select all

dim counter as int

counter=0
do
delay_Cyc(Clock in Mhz)
inc(counter)
while (1000*12)

It's ok or NOT???

If yes what do you think of that:

program PW_High; 

//Program measures the logic High portion of a pulse train based on a pulse input and displays the PW in milliseconds 
//NOTE: Interrupt Procedure is NOT  used as the CCP2 interrupt flag is set regardless 
//of whether interrupt is enabled.  Since the CCP2IF is checked in the Main repeat loop, there is no 
//need for the MP3 Interrup Procedure. 

uses PW_Acq_High;  //Determines logic Hign period time based on Timer TMR1 
               //Note this works for an 18F452 with a 4 Mhz crystal 
                //MP3 Default Configuration  for 18F452 chip was used for chip configuration 
               ////Note:  18F452 Chip is configured so that CCP2 is on pin RC1 
               // rather than RB3  __CONFIG _CONFIG3H_OFF 
               //Pulse train must be +5V (Pluse logic High) and 0 volts (Pulse Logic Low) 
//GLOBAL VARIABLE
PW :Word; //Holds PW Logic High time calculated 

Procedure Pulseout_µs(time:WORD;clock:BYTE) // Function like variable timer with "time" as time in µs to reach and "clock=4" for 4 Mhz clock

begin
Var
counter: int;// Counter that count as long as time is reach
counter=0;// Initialize counter

PORTB.0 := 1;  //Turn on PW Logic High the pin that you choose
do
delay_Cyc(clock)
inc(counter)
while (time)
PORTB.0 := 0;  //Turn off PW Logic High the pin that you choose
end;

Procedure Initialize_LCD;   //This must be tailored for your particular LCD set up 
  begin 

       LCD8_Config(PORTC,PORTD,6,4,5,7,6,5,4,3,2,1,0); //RS,EN,RW  Data Use in Real Fuel board Initialze LCD through PORTs 
       LCD8_Cmd(Lcd_Clear);//Clear LCD display 
       LCD8_Cmd(Lcd_Cursor_Off);//Turn visible cursor off 

  end; 

Procedure Initialize_Ports; 
  begin 

      TRISD:= $00;  //Set all PORTD for output 
      PORTD:= $00; 
      TRISC:= $02;  //   0000 0010  Set  bit RC1 for CCP2 input, RC6,4,5(Rs/En/RW) LCD control Output 

  end; 

Procedure Initialize_Timer_CCP; 
   begin 

      INTCON := $00;  //Disable all Interrupts for initialization of other registers 
      T3CON  := $00;  //0000 0000  was $C0 Sets Timer1 as source clock for CCP1 and CCP2 leaves timer3 off 
      CCP2CON:= $05;  //set for 1th rising edge 
      T1CON  := $01;  //set for 8 bit time read, prescaler of 1 and turn timer 1 on 
      TMR1L  := $00; //zero timer registers 
      TMR1H  := $00; 

   end; 


Procedure Display_PW(PW:word); 
    var Txt: array[6] of char; 
        Txtstr: array[12] of char; 
    begin 
         Txt := '  '; //Intialize Txt 
         TxtStr := ' MP3 PW High'; 
         LCD8_OUT(1,1,Txtstr); 
          TxtStr := 'X.XX msec';   //Displayed when Pulse train to CCP2 is active 
         LCD8_Out(2,8,Txtstr); 
         Wordtostr(PW,Txt); 
         LCD8_OUT(2,1,Txt); 

    end; 

Procedure CCP2_Call;   //Calls CCP2_PW to get pulse interval of rotation period then calculates and displays PW 
     Var 
           PW_L  :byte; //Bytes to hold pulse time information from Tach_Acq_High unit 
           PW_H  :byte; 
           

   Begin 

           PW_L := 0;//Variables for Rotation Period Time 
           PW_H := 0; 
     If testbit(PIR2,CCP2IF) = 1   then //If CCP2 flag is set then pulse has triggered CCP2 module 
      begin 

         ccp2_PW( PW_H,PW_L); //Calls to Data_Acq unit for pulse measurements 
            if (CCP2CON = $05) AND (CCP2IF = 0) then    //update viariable values and make calculation  after finished with entire timeing sequence 
             begin 

                   
                  PW   := Word(PW_H shl 8) OR PW_L;//combined hi and low byted of High Pulse period into word 
                  PW  := PW div 10; 
                   //Calculate PW(period is in clock cycles this turns it into milliseconds) 
                                          //Conversion value valid for a 4 Mhz oscillator frequency ONLY 
                  Display_PW(PW); //Displays PW Data 

              end; //If (CCP2CON =5 ..... 


     ClearBit(PIR2,CCP2IF);//Clear ccp2 Flag for next cycle 
      end; 

   end; 

begin  //Main part of program 
    Initialize_Ports; 
    Initialize_LCD; 
    Initialize_Timer_CCP; 
    PW   := 00; // initialize timer period

    Repeat     //Loop forever calling CCP2_Call to determine rotation period and calculate PW 

      CCP2_call;    //Call for Data and displayPW based on CCP2 module response to a pulse train 

    until true = false; 
end. 

//Next is Unit 

unit PW_Acq_High; 


implementation 



Procedure ccp2_PW(Var PW_H,PW_L:byte);//CCP2_Fuel; 

  //This procedure is to measure the period of a pulse train to pin RC2. 
 //  

 // Note:  The procedure is set up to interrupt on the 1st rising edge of a pulse  CCPXCON := 05 

 //****************************  Start of timing sequence ********************************************************* 
//                     <--- -> 
// '   ''''''''''|       |'''''''''  ''|       |'''''''''''        
//            |.......|           |.......|                    
//                    1stRE     FE       RE 
//                  start  Time   Stop Time 

//**************************************************************************************************************** 



  //********************************************************************* 
  //Note:  18F452 Chip is configured so that CCP2 is on pin RC1 rather than RB3  __CONFIG _CONFIG3H_OFF 
  //********************************************************************* 

 //The rising edge CCP2 capture set as CCP2Con := $05  Must also reset value in main pgrom in CCP2 Initialization procedure 
 //and CCP2_Call Procedure (where If statement signifies end of timeing sequence) 
  Var 

      Pulse_HSL  :byte; //Hold Rise Edge time for start of timing sequence 
      Pulse_HSH  :byte; 

      Pulse_LSL  :byte; //Hold Falling Edge time ( end of logic High) 
      Pulse_LSH  :byte; 
     TPulse_EL  :byte; //temp variable for pulse High Logic (Low byte) 
     TPulse_EH  :byte; //Temp variable for Pulse High Logic  (High byte); 

begin          //Start measurement with pulse going low (falling), end measurement with pulse going high (rising) 
  ClearBit(INTCON,GIE);                       //clear GIE to prevent further interupts while handling this one 

   if TestBit(PIR2,CCP2IF) = 1 then            //Is it CCP2 Interrupt? 
       begin    //Yes, it is CCP2 Interrup. 
         // The CASE section determines which code section processes the request, Start_Time, Fall_Edge or 2nd Rise_Edge 

          case CCP2CON of   //Note: CCP2CON := $05 (  Rising edge) 
          $05:  //This STARTS TIMING SEQUENCE, get start time of every  rising edge - Leave and wait for next falling ($04) Edge of pulse train 
               //*******  Captures Start time of pulse sequence (Rising edge  *****************************************************= 
                              begin 

                  Pulse_HSL := CCPR2L;      //Get captured pulse high start time low byte     *******Change back to CCPR1L ***** 
                  Pulse_HSH := CCPR2H;       //Get captured time high byte 

                  CCP2CON := $04;          //Set to capture next Falling edge 
                  ClearBit(PIR2,CCP2IF);   //Reset to preclude False Interrupt 
                  
                  Pulseout_µs(( PW div 10000) ;4); // I generate my pulseout= pulsein/10 in µs
          end; 
          $04:  //This detects the falling edge which is the end of the pulse logic HIGH 
                    begin 

                   Pulse_LSL   := CCPR2L;  //Ge start time of low Logic zero = end of Logic High 
                   Pulse_LSH   := CCPR2H; 
                   TPulse_EL:=Pulse_LSL;  //Hold time value 
                   TPulse_EH:=Pulse_LSH; 
                    
                   PW_L     := Pulse_LSL - Pulse_HSL;  //Calculate Pulse High  Time   low byte 
                  IF TestBit(STATUS,C) = 0 then       //if Borrow required reduce high value of TPulse_H by 1 
                     TPulse_EH := TPulse_EH - 1; 
                   PW_H     := TPulse_EH - Pulse_HSH;  //Calculate Pulse High Time High byte 
                        //ReSet for Rising Edge Capture on next entry into ISR 


                   CCP2CON := $05;          //ReSet for Rising Edge Capture on next entry into this CCP2_PW Routine 
                   ClearBit(PIR2,CCP2IF);   //Clear in case of false interrupt when changin mode 
             end; 


          end;//case 

       end;  // end of IF Statement CCP2_Inj 

   end; 

end.

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Time Delay

#41 Post by Rotary_Ed » 10 Oct 2005 22:56

I think I understand your Approach to the timing problem.

4MHZ Osc/4 = 1 MHZ Clock = 1 usec per clock cycle = 1 x10^-6 sec.

1x10^-6 * 1x*10^3 = 1x10^-3 or 1 millsecond every 1000 clock cycles

I do not understand where the 12 comes from? Is this the number of milliseconds delay you want??

If you want 12 milliseconds then you must turn the pulse on for 12000 clock cycles for a 4 Mhz oscillator


So 12 Milliseconds = 12*1000 = 12000 clock cycles

The question is how do you measure your 1000 clock cycles? I presume that is what your procedure

delay_cyc(4) will do.

Will delay_cyc(4) = 1000 clock cycles = 1000 usec?? = 1 millisecond??

If delay_cyc(4) = 1000 clock cycle delays then I think your code should read something like this for what ever language you are using:

Counter : variable

Repeat
delay_cyc(4) ;Delay 1000 clock cycles or 1 millisecond
inc(counter) ;Increment counter after 1 millisecond
until Counter = 12;when counter = 12 then 12*1000 clock cycles = 12 milliseconds

Again, that is if I understand what you are trying to accomplish and if delay_cyc(4) will give 1000 usec delay
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

ghspirit
Posts: 22
Joined: 07 Oct 2004 10:25

Delay_Cyc(4)=1ms ???

#42 Post by ghspirit » 10 Oct 2005 23:32

hello,

thanks for your help! 12 ms is for example! I understand more better timing problem with pic now!

In fact to do 1000 cycles and make 1 ms you must put Delay_Cyc(100) and not Delay_Cyc(4)!

Well i test it tomorrow and tell you the result!

See MB manual:

Delay_Cyc
Prototype void Delay_Cyc(unsigned Cycles_div_by_10);

Returns Nothing.

Description Creates a delay based on MCU clock. Delay lasts for 10 times the input parameter in MCU cycles.

Note that Delay_Cyc is library function rather than a built-in routine; it is presented in this topic for the sake of convenience.

Requires Nothing.

Example Delay_Cyc(10); /* Hundred MCU cycles pause */



Best regards and Thanks for all your time ;-)

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Delay_

#43 Post by Rotary_Ed » 11 Oct 2005 00:52

I am not aware of that procedure. I will have to check MB. Thanks for the tip.

Sounds to me that you have found what you need.

Good Luck with the rest of your project
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

wwwhelp
Posts: 33
Joined: 17 Jan 2005 13:11

#44 Post by wwwhelp » 31 Oct 2005 08:57

Hello everyone,
I try some of examples and thay work ok but can you tell me please how can I modify the source for tahometer for 12F629 chip. I need only read RPM and if for example RPM = 1500 some output be set to 0 or 1.

Thank you in advance

Rotary_Ed
Posts: 756
Joined: 26 Dec 2004 23:10
Location: Matthews, NC, USA
Contact:

Tach

#45 Post by Rotary_Ed » 03 Nov 2005 14:46

I am not certain which code for Tach you are referring to. However, in the MB code shown, assuming PW is a global variable and represents the RPM. So I would think if you added an line of code in the "REPEAT" loop something like the following:

If PW>=1500 then Flag := 1 else Flag := 0;

It should work


begin //Main part of program
Initialize_Ports;
Initialize_LCD;
Initialize_Timer_CCP;
PW := 00; // initialize timer period

Repeat //Loop forever calling CCP2_Call to determine rotation period and calculate PW

CCP2_call; //Call for Data and displayPW based on CCP2 module response to a pulse train
If PW>=1500 then Flag := 1 else Flag := 0;//ADDED CODE
until true = false;
end.

//Next is Unit

unit PW_Acq_High;
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered

Post Reply

Return to “mikroPascal General”