Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of IEEE_14_Freescale by
hcsr04.h
- Committer:
- sswatek
- Date:
- 2014-03-23
- Revision:
- 33:03b0b66038e1
- Parent:
- 31:4ef53fbd6759
File content as of revision 33:03b0b66038e1:
// Primary Author: David Glover
// March, 2012
// ECE 510 Embedded Systems, Roy Kravitz
//
// HCSR04 ultrasonic sensor class using interrupts and allowing multiple instances.
// You can use the same trigger pin for multiple instances; the echo is received and
// measurement calculated based on the echo input alone. (when the echo signal goes high,
// the timer is started. When the echo signal goes low, the timer value in microseconds
// is saved as the length, and the timer is stopped and reset) Length calculation is done
// when the length is requested (either inches or centimeters).
#ifndef MBED_HCSR04_H
#define MBED_HCSR04_H
//required to use mbed functions
#include "mbed.h"
#define TRIGGER_DELAY 12 // length of trigger signal expected by HCSR04 sensor
#define INCHES_DIVISOR 139 //
#define CM_DIVISOR 58
class hcsr04 {
private:
InterruptIn *_echo_int; // pin to receive echo signal; input
DigitalOut trigger_out; // pin to send the trigger signal; output
Timer timer; // timer to track length of pulse
volatile float value; // to store the last pulse length
public:
bool measuring; // true while the echo signal is high (measurement in progress)
hcsr04(PinName trigger, PinName echo) : trigger_out(trigger) { // _pass the names to the pin configuration
//trigger_out = new DigitalOut( trigger );
_echo_int = new InterruptIn( echo ); // interrupts
_echo_int->rise(this, &hcsr04::timer_start); // when trigger is sent
_echo_int->fall(this, &hcsr04::calc_measurement); // when echo is received
measuring = false;
}
void calc_measurement() {
value = timer.read_us();
//value = timer.read_us() - timestart;
timer.stop();
timer.reset();
measuring = false;
}
void timer_start() {
timer.reset();
timer.start();
//measuring = true;
}
void trigger(void) {
trigger_out.write(1); // start trigger signal
wait_us(TRIGGER_DELAY);
trigger_out.write(0); // end trigger signal
measuring = true;
timer.reset();
timer.start();
}
float inches() { // return distance in inches.
return value / INCHES_DIVISOR;
}
float cm() { // return distance in centimeters.
return value / CM_DIVISOR;
}
//finds a stable distance value by taking count samples and putting them into buckets
// of +-%10 that are moving averages
// returns the distance in inches of a measurement with at least thresh results
// returns -1 if no consensus was found and returns -2 if none of the samples were less than 19 inches away
// which would indicate a "far" read
float getStablePollAdv(int count, int thresh){
float distBuckets[7] = {0,0,0,0,0,0,0};
int bucketCount[7] = {0,0,0,0,0,0,0};
for(int i=0;i<count;i++){
trigger();
while(measuring && timer.read_ms()<200);
if(!measuring){
//store value
for(int j=0;j<7;j++){
if(bucketCount[j]==0){
//bucket empty, add to bucket
distBuckets[j]=value;
bucketCount[j]++;
break;
} else if(value > distBuckets[j]*0.9 && value < distBuckets[j]*1.1){
//within range of center bucket, add
distBuckets[j] = (distBuckets[j]*bucketCount[j]+value)/(bucketCount[j]+1);
bucketCount[j]++;
break;
}
}
}
}
int maxBucket=0;
int numBelowCutoff=0; // this is used to track if any values are below a cutoff
const float cutoff=19.0 * INCHES_DIVISOR;
if(distBuckets[0]<cutoff)
numBelowCutoff += bucketCount[0];
//DBGPRINT("Bucket #0 has %d at %f\r\n",bucketCount[0],distBuckets[0] / INCHES_DIVISOR);
for(int i=1;i<7;i++){
// cycling through the values to find the bucket with the most members
if(distBuckets[i]<cutoff)
numBelowCutoff += bucketCount[i];
//DBGPRINT("Bucket #%d has %d at %f\r\n",i,bucketCount[i],distBuckets[i] / INCHES_DIVISOR);
if(bucketCount[maxBucket]<bucketCount[i])
maxBucket=i;
}
if(bucketCount[maxBucket]>=thresh){
return distBuckets[maxBucket] / INCHES_DIVISOR;
} else if(numBelowCutoff==0){
return -2;
}else{
return -1;
}
}
// (15,8) seems to give good results, so this convienence function can be used for these defaults
float getStablePoll(void){
return getStablePollAdv(15,8);
}
/* void hscr04_main(void) { // Rohan's code
//trigger();
// delay
while(measuring == false);
// interrupts call timer_start() and calc_measurement()
}
*/
};
#endif
