Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

how to capture pusle width using pic microcontroller?

Status
Not open for further replies.

rashidme

Member
Hello,

I am using PING))) ultrasonic sensor,connected to pic18f4520, to measure distance. The sensor sends out a pulse to the pic and the width of the pulse determines the distance. How can i find the width of the pulse? I am guessing i need a timer. But i am not too sure about the sequence that i have to go through.

Thank you.
 
With a timer i would use timerO

This is in swordfish basic I was using it to count Frequency

Code:
Device = 18F1220
Clock = 8 // 8MHz clock
Config OSC = INTIO2, WDT = OFF, LVP = OFF
Include "IntOSC8.bas"
Include "LCD.bas" 
Include "utils.bas" 
Include "Convert.bas"
 
// some LCD options...
#option LCD_DATA = PORTB.4
#option LCD_RS = PORTB.2
#option LCD_EN = PORTB.3
Dim button As PORTA.0 
Dim timer0_ON As T0CON.7
Dim timer0_OFF As T0CON.7
Dim TMR0 As TMR0L

//////////// sets up the timer0
Sub set_timer ()
T0CON.7 = 1 //sets timer0 on
T0CON.6 = 0  //sets to 16 bit timer
T0CON.5 = 1 //sets transition on T0CKI pin
T0CON.4 = 1 //sets hight to low transtion
T0CON.3 = 0 // turns on prescaler
T0CON.2 = 1
T0CON.1 = 1  //sets prescaler to 1:256
T0CON.0 = 1
TMR0 = 0 
INTCON.5 = 1
End Sub 
//////////////////////////////////////
Sub Get_fq()
     Dim Acc_byte0 As Byte      'You can't use a . here  so I change theat to underscore
    Dim Acc_byte1 As Byte
    Dim Acc_byte2 As Byte
    Dim value As LongWord
    
//
// Timer0 frequency counter example, Mike McLaren, K8LH
//
  TMR0H = 0                // clear Timer0 registers
  TMR0L = 0                //
 
  Input(PORTA.4)           // gate Timer0 counter "on"
  DelayMS(10)            //
  Output(PORTA.4)          // gate Timer0 counter "off"
 
  Acc_byte0 = 0            // count bits 00..07 (prescaler)
  Acc_byte1 = TMR0L        // count bits 08..15
  Acc_byte2 = TMR0H        // count bits 16..23
  //
//  toggle timer0 "source edge select" bit to 'bump' the prescaler
//  until it overflows into the TMR0L register
//
  While (TMR0L = Acc_byte1)
    T0CON.4 = 1            // toggle T0SE "source edge select" bit
    T0CON.4 = 0            //
    Dec(Acc_byte1)         //
                   //
 
 While true (TMR0L = Acc_byte1)
    value = Acc_byte1
    
      LCD.MoveCursor (1,1)
   LCD.Write(BinToStr (value))
 Wend
Wend    
End Sub 
 
//////////////////////////////////////
ADCON1=$70     //sets portb Digital
timer0_ON = 1   // turns timer0 on
timer0_OFF = 0  // turns timer0 off
SetAllDigital
While true
        //set_timer
       
    Repeat
        If button = 1 Then
           
        EndIf
       
        WriteAt(1,1,"Frequency Counter")
        DelayMS(500)
    Until button = 0 
         Cls  
        Get_fq       // just for testing           
Wend

Mike McLaren, K8LH
wrote the sub I'm using
 
Last edited:
ok so here is my code. And I can't seem to measure distance. I dont know if i am doing it right?

Code:
/********************************************************************
;* FileName:        ultrasonic.c
;* Processor:       PIC18F4520
;* Compiler:        MPLAB C18 v.3.06 
;*
;* (description)
;* uses Ping))) ultrasonic sensor for distance measurements.
;*
*/


/** Processor Header Files ****************************************/
#include <p18f4520.h>
#include <delays.h>

// === Configuration Bits =======================================
//
#pragma config OSC = HS	//for high speed, 10Mhz crystal or greater.
//#pragma config OSC = EC // External 4MHz crystal for PICDEM board only
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config BOREN = OFF


void INIT_PORTS(void)
{
	/* Make ports digital */
	ADCON1 = 0x0F;
	
	/* Make port B output */
	PORTB = 0x00;
	TRISB = 0x00;
	
	/* Make port C input for CCP1(RC2) */
	PORTC = 0x00;
	TRISC = 0x04; 
}

/* Trigger pulse to start the PING. 2us  */
void triggerPulse(void)
{
	TRISC = 0x00;
	
	PORTCbits.RC2 = 1;
	Delay1TCY();
	PORTCbits.RC2 = 0;
}

void INIT_TMR(void)
{	
	PIR1 &= 0x00;			//reset  INT flags
	T3CON = 0b10000000;		//use timer1 for ccp module
	T1CONbits.RD16 = 1;
	T1CONbits.T1RUN = 0;
	T1CONbits.T1CKPS1 = 0;
	T1CONbits.T1CKPS0 = 0;
	T1CONbits.T1OSCEN = 0;
	T1CONbits.T1SYNC = 0;
	T1CONbits.TMR1CS = 0;
	T1CONbits.TMR1ON = 1;	//enable timer 1
}	

/*****************************************************************
* Function: void main(void)
******************************************************************/
#pragma code


void main (void)
{
	unsigned int ccprl = 0, ccprh = 0;
	long unsigned int ccprVal = 0;
	
	INIT_PORTS();
	INIT_TMR();
	
	CCP1CON = 0x05; 		//capture mode, every rising edge
	PIR1bits.CCP1IF = 0;	//clear capture interrupt flag	
	
	while (1) 
	{
	
		triggerPulse();
		Delay10KTCYx(185);	//hold off time
		TRISC = 0x04;
		
		/* When a capture is made PIR1bits.CCP1IF bit is set 
		   We wait here untill a capture is made */
		while (!PIR1bits.CCP1IF); 
		
		PIR1bits.CCP1IF = 0;
		ccprl = CCPR1L;
		ccprh = CCPR1H;
		ccprVal |= ccprh;
		ccprVal <<= 8;
		ccprVal |= ccprl;
		ccprVal /= 2;
		ccprVal = ccprVal / 1000;
		
		ccprVal = 0;
	}	//end while

}	//end main
 
I'm no big C person but Looks like you would

Use Trigger Pulse of 5us the datasheet said 2 μs (min), 5 μs typical

Test that pin went low then catch the rising edge count how long it takes to get back low

Holdoff time 750 μs

Are you setting the pin back to input
direction = output then it needs to be a input
 
Yes i am using trigger pulse
Code:
 /* Trigger pulse to start the PING. 2us  */
void triggerPulse(void)
{
	TRISC = 0x00;
	
	PORTCbits.RC2 = 1;
	Delay1TCY();
	PORTCbits.RC2 = 0;
}

it worked by catching the rising edge and then catching the falling. Doing a difference T2 - T1 gives me the width.
Thank you.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top