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.

Parallax Ping Sensor

Status
Not open for further replies.

AtomSoft

Well-Known Member
Hey guys im trying to use this Ultrasonic Ping Sensor from parallax but to me the documentation is all wrong.

https://www.electro-tech-online.com/custompdfs/2009/09/28015-PING-v16.pdf

If you look at the below image from the manual you can see tBurst.. Looks like a normal pwm style data coming from the sensor.

But in reality its a single long wave. (solid high)

ping-jpg.33420


I have some code to get the numbers but i know it has to be wrong because im never right the first time.

Code:
void GetPing(void){
	unsigned int MyPing = 0;
	char Done = 0;
	
	PingDir = 0;

	PingOut = 0;
	Delay16uS();
	PingOut = 1;
	Delay10TCY();
	PingOut = 0;

	PingDir = 1;
	PingIn = 0;
	while(!PingIn);

	while(PingIn){
		MyPing++;
	}
}

MyPing variable show contain the length of the high pulse ... but how do i convert that to CM? or better yet Inches?

This module supposed to work from 3CM to 3M
 

Attachments

  • ping.jpg
    ping.jpg
    53.6 KB · Views: 1,556
I was thinking about using a timer and just turn it on when the high is detected and off when its low then have a variable incremented every interrupt then add the last timer value to that variable to get a complete count but not sure if thats wise either.
 
Set up a timer to run forever
Set up your input to interrupt on rising edge
Transmit your "go" pulse
Enable your interrupt

On interrupt
- Read timer counter into variable start_time
- Set up interrupt to occur on falling edge

On interrupt
- Read timer counter into end_time
- Set process flag
- Set up interrupt to occur on rising edge

Code:
while (1)
{
  if process_flag
    flight_time = end_time - start_time
    flight_time *= conversion factor from timer counts to cm
    clear process_flag
}

To get the conversion factor you have to know how many timer ticks you get per second and the ping boards conversion factor from detected distance to output pulse time

Using while(PingIn) MyPing++; may result in different times if you change compiler optimizations or the compiler changes or you get an interrupt etc
tBurst is the length of the ultrasonic transmission. If you scope the pins on the transmitter, you'll see that pulsed waveform for 200uS at 40kHz
 
Last edited:
Will the interrupt get called when i send my pulse since its all on 1 i/o pin. I have to set it to output to trigger the device then input to read the data on same pin
 
That would probably call the interrupt, so disable the interrupt on the falling edge and enable it at the end of your GetPing function
 
The max time is around 19mS should i use a 16 bit timer? I was thinking if its too long the start time can be 0x30 and end time 0x20 because it goes 0 - 255 - 0 - 255 what if i fall on a 0 as the end time?
 
Last edited:
The max time is around 19mS should i use a 16 bit timer? I was thinking if its too long the start time can be 0x30 and end time 0x20 because it goes 0 - 255 - 0 - 255 what if i fall on a 0 as the end time?

If you get an overflow, time would be 0x100 - start time + end time. However, if you did end time - start time, you'd still get the same result if you cast it as an unsigned 8 bit integer.

Assume a start time of 0x20 and an end time of 0x30. It is easy to see that the time difference is 0x10 counts.

Assume a start time of 0x30 and an end time of 0x20. Logically, 0x10 more counts would make it an even 0x100 counts, so your time is 0xF0. You can mathematiically come to this answer two ways:
1. 0x100 - 0x30 + 0x20 = 0xF0
2. 0x20 - 0x30 = 0xFFFFF.....FFFF0 which is type casted to an 8 bit value of 0xF0

As for the first question, you can either use a 16 bit timer or use a larger prescaler at the cost of a loss of precision in measuring the pulse width.
 
any idea why this wont interrupt?

Code:
void initPIC(void){
	TRISA = 0x00;
	TRISB = 0x00;
	TRISC = 0x00;

//----------------------
// PING INIT			
//----------------------
	PingDir = 0;		//PING pin is output
	PingOut = 0;		//Start with PING pin LOW
//----------------------
// Buzz INIT			
//----------------------
	BuzzDir = 0;
	BuzzOut = 0;
//----------------------
// Timer0, INT0 INIT			
//----------------------
	T0CON   = 0b10001000;	//16 Bit Timer
	INTCON  = 0b11000000; 	//bit 1 = INT0IF
	INTCON2 = 0b10000001; 	//bit 6 = rising edge(1)
	RCON    = 0b10000000;  	//IPEN = 1
}

void GetPing(void){

	INTCON2bits.INTEDG0 = 1;

	Ping.start = 0;	
	Ping.end = 0;
	Ping.start = 0;

	PingDir = 0;

	PingOut = 0;
	Delay16uS();
	PingOut = 1;
	Delay16uS();
	PingOut = 0;

	INTCONbits.INT0IF =0;
	INTCONbits.INT0IE = 1;

	PingDir = 1;
	PingIn = 0;


	while(intFlag == 0);
	INTCONbits.INT0IE = 0;
	INTCON2bits.INTEDG0 = 0;
	INTCONbits.INT0IF =0;
	INTCONbits.INT0IE = 1;
	while(intFlag == 1);

}
 
Why not consult the documentation? - here's simple BS1 code to read it.

Code:
Get_Sonar:
  LOW Ping                                      ' make trigger 0-1-0
  PULSOUT Ping, Trigger                         ' activate sensor
  PULSIN  Ping, IsHigh, rawDist                 ' measure echo pulse
  rawDist = rawDist * Scale                     ' convert to uS
  rawDist = rawDist / 2                         ' remove return trip
  RETURN
 
Jason

Don't know if this helps

PULSIN

In a similar manner to sending a PWM signal, we can also read a PWM signal from an external device. We must specify which port we are reading from, and we must also provide a variable to receive the length of the pulse. For instance, if we wanted to read a PWM pulse on port 5, we could write:

MyByte VAR Byte
PULSIN 5, MyByte

Like with PULSOUT, the units of time are 2 μs.

One common device that uses PWM input like this is the Parallax ultrasonic sensor. These sensors return a pulse for a length of time equal to the amount of time it takes sound waves to travel to an object and bounce back. Using some simple arithmetic, if we know the speed of sound and if we know the amount of time, we can calculate the distance of the object.

Rupert
 
Jason

Is this any help?

Code:
void ping(void) {

    PORT_ON(DDR, PINGPIN);   // Switch PingPin to OUPUT
// ------Trigger Pulse--------------
PORT_OFF(PORT, PINGPIN);   // Bring PingPin low before starting trigger pulse
delay_us(2);        //  Wait for 2 microseconds
PORT_ON(PORT, PINGPIN);    // Bring PingPin High for 5us according to spec sheet.
delay_us(5);       // Wait for 5 microseconds
PORT_OFF(PORT, PINGPIN);; //  Bring PingPin Low and standby
//--------End Trigger Pulse---------------------
FLIP_PORT(DDR, PINGPIN);   // Switch PingPin to INPUT
loop_until_bit_is_set(PIN, PINGPIN);     // Loop until the the PingPin goes high  (macro found in sfr_def.h)
//clears timer, reset overflow counter
reset_timer_0();       //reset timer 0
loop_until_bit_is_clear(PIN, PINGPIN);     // Loop until the the PingPin goes low  (macro found in sfr_def.h)
//read timer0's overflow counter
//255 is count before overflow, dependent on clock
int elapsed_time=timer0GetOverflowCount()*255+TCNT0;
PingVal = elapsed_time * 2.068965517;t
} // end ping function

This is from another site I just found.

Rupert
 
Thanks ill conver that in a min. I have to step out gonna pick up check from work :)

thanks again guys for helping. I know im a slow pain. But when i learn i can teach :D
 
Jason

The full article is here if you need it.

Rupert
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top