Parallax Ping Sensor

Status
Not open for further replies.
this sucks. If its so simple how come no one can give a straight answer.

The algorithm I gave you earlier is very close to what I do with a similar sensor. It sounds to me like your MCU just wasn't interrupting. You only posted partial code so I didn't see how I could help.

Did you enable interrupts? Did you write your interrupt routines? What is intFlag? Was it declared as volatile?
 
The simplest way to do it is;

1. Make trigger pulse
2. Poll to test if signal when high
2. Reset TMR1
3. Poll to test if signal goes lo
4. Stop TMR1
5. subtract constant Tin-min from TMR1
6. TMR1 now contains the distance

the 2 poll delays will cancel each other out on average. Generally you want to average a few readings anyway.
 
Take a look:
Main2.c
Code:
// include files
#include <p18cxxx.h>
#include "main2.h"

// config settings
#pragma config WDT = OFF, LVP = OFF, OSC = INTIO67, XINST = OFF

// global vars
PingData Ping;
unsigned char intFlag;

// interrupts
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO High_ISR _endasm
}

#pragma code low_vector=0x18
void interrupt_at_low_vector(void)
{
_asm GOTO Low_ISR _endasm
}

// code
#pragma code

#pragma interruptlow Low_ISR
void Low_ISR()
{
}

#pragma interrupt High_ISR
void High_ISR()
{
	INTCONbits.INT0IF =0;
	if(intFlag == 0){
		Ping.start = TMR0L;
		Ping.start = TMR0H;
		Ping.start <<= 8;
		Ping.start |= TMR0L;
		intFlag = 1;
	} else {
		Ping.end = TMR0L;
		Ping.end = TMR0H;
		Ping.end <<= 8;
		Ping.end |= TMR0L;	
		intFlag = 0;
	}

}

void main()
{
	OSCCON = 0x72;      			//8MHz clock 500ns cycles
	while(!OSCCONbits.IOFS);		//wait for osc stable

	intFlag = 0;
	initPIC();
	while(1)
	{
		GetPing();
	}
}

// function definitions
void PlayTone(void){
	unsigned char x;
	for(x=0;x<20;x++){
		BuzzOut = 1;
		Delay10KTCYx(5);
		BuzzOut = 0;
		Delay10KTCYx(5);
	}
		BuzzOut = 0;
}
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);

}

//------------------------------------------------------
// Used MPLAB Stopwatch. Exact 16uS from call to return.
//------------------------------------------------------
void Delay16uS(void){
	Delay10TCY();
	Nop();Nop();
}
//------------------------------------------------------
// Used MPLAB Stopwatch. Exact 400uS from call to return.
//------------------------------------------------------
void Delay400uS(void){
	Delay100TCYx(3);
	Delay10TCYx(9);
	Nop();Nop();Nop();Nop();Nop();Nop();
}
main2.h
Code:
//main2.h
#ifndef __MAIN2_H
#define __MAIN2_H
#include <delays.h>

void main(void);
void initPIC(void);
void GetPing(void);
void Delay16uS(void);
void Delay400uS(void);
void PlayTone(void);

void Low_ISR(void);
void High_ISR(void);

#define PingDir  TRISBbits.TRISB0
#define PingOut  LATBbits.LATB0
#define PingIn   PORTBbits.RB0

#define BuzzDir  TRISCbits.TRISC2
#define BuzzOut  LATCbits.LATC2

typedef union {
	struct {
		unsigned int start;
	};
	struct {
		unsigned int end;
	};
	struct {
		unsigned int len;
	};
}  PingData;  
#endif
 

Would try now but am tired. gonna try in about 10 min
 
From PIC datasheet (18F2525)


Does this mean i have to read the TMR0L then the TMR0H ? like:

Code:
	Time = TMR0L;
	Time = TMR0H;
	Time <<= 8;
	Time |= TMR0L;
 
Ok this is giving me a stable number:
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);
	T0CONbits.TMR0ON = 1;
	
	while(PingIn);

	T0CONbits.TMR0ON = 0;

	Time = TMR0L;
	Time = 0;
	Time = TMR0H;
	Time <<= 8;
	Time |= TMR0L;

	TMR0L = TMR0H = 0;
}
 
Looks good but i'd use a 16bit var for time and change the end to this for better accuracy as you can subtract Tin_min before you reduce resolution;

Code:
	Time = TMR0L;
	Time += (TMR0H << 8);
	Time -= Tin_min (important)
(then reduce Time resolution if needed)
 
Last edited:
i got this which checks 3 times and averages them...
Code:
void GetPing(void){
	unsigned char x;
	unsigned int MyPing;
	char Done;

for(x=0;x<3;x++){
	Done = 0;
	MyPing = 0;
	
	PingDir = 0;

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

	PingDir = 1;
	PingIn = 0;
	while(!PingIn);
	T0CONbits.TMR0ON = 1;
	
	while(PingIn);

	T0CONbits.TMR0ON = 0;

	avg[x] = TMR0L;
	avg[x] += (TMR0H << 8);

	TMR0L = TMR0H = 0;

}
	Time = 0;
	Time = (avg[0] + avg[1] + avg[2]) / x;
}

Now to the tougher part. Converting into inches
 
Last edited:
heh i dont even need actual distance. I want to calculate the distance between 2 objects (cars) and just alarm when too close and the closer you get the more it alarms.

The further away the less until a safer distance and no alarm.

I think i can do it from here .. Ill post my final code when its done... thanks guys
 
Yay its beautiful... ima make a video:
Code:
#include <p18f2525.h>
#include "main.h"
#include <delays.h>

#pragma config WDT = OFF, LVP = OFF, OSC = INTIO67, XINST = OFF

unsigned int Time;
unsigned int avg[3];

void main(void){
	unsigned float temp = 0;
	unsigned char speed,length;
	OSCCON = 0x72;      			//8MHz clock 500ns cycles
	while(!OSCCONbits.IOFS);		//wait for osc stable

	initPIC();

	while(1){
		GetPing();
		speed = 0;
		SetLED(0xFF);
		if(Time < 50){
			speed = 3;
			length = 5;
			SetLED(2);
			goto PlayIt;
		}
		if(Time < 80){
			speed = 6;
			length = 5;
			SetLED(1);
			goto PlayIt;
		}
		if(Time < 125){
			speed = 9;
			length = 5;
			SetLED(0);
			goto PlayIt;
		}
PlayIt:
		if(speed>0)
			PlayTone(speed,length);

	}

}
void SetLED(char led){
	LED0 = LED1 = LED2 = 0;

	if(led == 0) LED0 = 1;	
	if(led == 1) LED1 = 1;
	if(led == 2) LED2 = 1;
}
void PlayTone(unsigned char time,unsigned char dur){
	unsigned char x;
	for(x=0;x<dur;x++){
		BuzzOut = 1;
		Delay10KTCYx(time*2);
		BuzzOut = 0;
		Delay10KTCYx(time/2);
	}
		BuzzOut = 0;
}
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;

	T0CON   = 0b00001000;

}

void GetPing(void){
	unsigned char x;
	unsigned int MyPing = 0;
	char Done = 0;
	
for(x=0;x<3;x++){
	PingDir = 0;

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

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

	while(PingIn){
		MyPing++;
	}

	avg[x] = MyPing / 10;
	Delay10KTCYx(15);
}
	Time = (avg[0]+avg[1]+avg[2]) / 3;

}

//------------------------------------------------------
// Used MPLAB Stopwatch. Exact 16uS from call to return.
//------------------------------------------------------
void Delay16uS(void){
	Delay10TCY();
	Nop();Nop();
}
//------------------------------------------------------
// Used MPLAB Stopwatch. Exact 400uS from call to return.
//------------------------------------------------------
void Delay400uS(void){
	Delay100TCYx(3);
	Delay10TCYx(9);
	Nop();Nop();Nop();Nop();Nop();Nop();
}

Forgot the main.h
Code:
//main.h
#ifndef __MAIN_H
#define __MAIN_H

void main(void);
void initPIC(void);
void GetPing(void);
void Delay16uS(void);
void Delay400uS(void);
void PlayTone(unsigned char time,unsigned char dur);
void SetLED(char led);

#define PingDir  TRISCbits.TRISC3
#define PingOut  LATCbits.LATC3
#define PingIn   PORTCbits.RC3

#define BuzzDir  TRISCbits.TRISC2
#define BuzzOut  LATCbits.LATC2

#define LED0  LATBbits.LATB0
#define LED1  LATBbits.LATB1
#define LED2  LATBbits.LATB2

#endif
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…