Sooner Competitive Robotics / Mbed 2 deprecated IEEE_14_Freescale

Dependencies:   mbed

Fork of IEEE_14_Freescale by IEEE 2014 Mbed

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