Sonar example with callbacks.

Committer:
sarahmarshy
Date:
Thu Sep 07 22:17:59 2017 +0000
Revision:
0:1713cdc51510
Initial commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sarahmarshy 0:1713cdc51510 1 #include "mbed.h"
sarahmarshy 0:1713cdc51510 2
sarahmarshy 0:1713cdc51510 3 /**
sarahmarshy 0:1713cdc51510 4 * Sonar class for the HC-SR04
sarahmarshy 0:1713cdc51510 5 */
sarahmarshy 0:1713cdc51510 6 class Sonar {
sarahmarshy 0:1713cdc51510 7 DigitalOut trigger;
sarahmarshy 0:1713cdc51510 8 InterruptIn echo; // calls a callback when a pin changes
sarahmarshy 0:1713cdc51510 9 Timer timer;
sarahmarshy 0:1713cdc51510 10 Timeout timeout; // calls a callback once when a timeout expires
sarahmarshy 0:1713cdc51510 11 Ticker ticker; // calls a callback repeatedly with a timeout
sarahmarshy 0:1713cdc51510 12 int32_t begin;
sarahmarshy 0:1713cdc51510 13 int32_t end;
sarahmarshy 0:1713cdc51510 14 float distance;
sarahmarshy 0:1713cdc51510 15
sarahmarshy 0:1713cdc51510 16 public:
sarahmarshy 0:1713cdc51510 17 /**
sarahmarshy 0:1713cdc51510 18 * Sonar constructor
sarahmarshy 0:1713cdc51510 19 * Creates a sonar object on a set of provided pins
sarahmarshy 0:1713cdc51510 20 * @param trigger_pin Pin used to trigger reads from the sonar device
sarahmarshy 0:1713cdc51510 21 * @param echo_pin Pin used to receive the sonar's distance measurement
sarahmarshy 0:1713cdc51510 22 */
sarahmarshy 0:1713cdc51510 23 Sonar(PinName trigger_pin, PinName echo_pin) : trigger(trigger_pin), echo(echo_pin) {
sarahmarshy 0:1713cdc51510 24 trigger = 0;
sarahmarshy 0:1713cdc51510 25 distance = -1;
sarahmarshy 0:1713cdc51510 26
sarahmarshy 0:1713cdc51510 27 echo.rise(callback(this, &Sonar::echo_in)); // Attach handler to the rising interruptIn edge
sarahmarshy 0:1713cdc51510 28 echo.fall(callback(this, &Sonar::echo_fall)); // Attach handler to the falling interruptIn edge
sarahmarshy 0:1713cdc51510 29 }
sarahmarshy 0:1713cdc51510 30
sarahmarshy 0:1713cdc51510 31 /**
sarahmarshy 0:1713cdc51510 32 * Start the background task to trigger sonar reads every 100ms
sarahmarshy 0:1713cdc51510 33 */
sarahmarshy 0:1713cdc51510 34 void start(void) {
sarahmarshy 0:1713cdc51510 35 ticker.attach(callback(this, &Sonar::background_read), 0.01f);
sarahmarshy 0:1713cdc51510 36 }
sarahmarshy 0:1713cdc51510 37
sarahmarshy 0:1713cdc51510 38 /**
sarahmarshy 0:1713cdc51510 39 * Stop the background task that triggers sonar reads
sarahmarshy 0:1713cdc51510 40 */
sarahmarshy 0:1713cdc51510 41 void stop(void) {
sarahmarshy 0:1713cdc51510 42 ticker.detach();
sarahmarshy 0:1713cdc51510 43 }
sarahmarshy 0:1713cdc51510 44
sarahmarshy 0:1713cdc51510 45 /**
sarahmarshy 0:1713cdc51510 46 * Interrupt pin rising edge interrupt handler. Reset and start timer
sarahmarshy 0:1713cdc51510 47 */
sarahmarshy 0:1713cdc51510 48 void echo_in(void) {
sarahmarshy 0:1713cdc51510 49 timer.reset();
sarahmarshy 0:1713cdc51510 50 timer.start();
sarahmarshy 0:1713cdc51510 51 begin = timer.read_us();
sarahmarshy 0:1713cdc51510 52 }
sarahmarshy 0:1713cdc51510 53
sarahmarshy 0:1713cdc51510 54 /**
sarahmarshy 0:1713cdc51510 55 * Interrupt pin falling edge interrupt handler. Read and disengage timer.
sarahmarshy 0:1713cdc51510 56 * Calculate raw echo pulse length
sarahmarshy 0:1713cdc51510 57 */
sarahmarshy 0:1713cdc51510 58 void echo_fall(void) {
sarahmarshy 0:1713cdc51510 59 end = timer.read_us();
sarahmarshy 0:1713cdc51510 60 timer.stop();
sarahmarshy 0:1713cdc51510 61 distance = end - begin;
sarahmarshy 0:1713cdc51510 62 }
sarahmarshy 0:1713cdc51510 63
sarahmarshy 0:1713cdc51510 64 /**
sarahmarshy 0:1713cdc51510 65 * Wrapper function to set the trigger pin low. Callbacks cannot take in both object and argument pointers.
sarahmarshy 0:1713cdc51510 66 * See use of this function in background_read().
sarahmarshy 0:1713cdc51510 67 */
sarahmarshy 0:1713cdc51510 68 void trigger_toggle(void) {
sarahmarshy 0:1713cdc51510 69 trigger = 0;
sarahmarshy 0:1713cdc51510 70 }
sarahmarshy 0:1713cdc51510 71
sarahmarshy 0:1713cdc51510 72 /**
sarahmarshy 0:1713cdc51510 73 * Background callback task attached to the periodic ticker that kicks off sonar reads
sarahmarshy 0:1713cdc51510 74 */
sarahmarshy 0:1713cdc51510 75 void background_read(void) {
sarahmarshy 0:1713cdc51510 76 trigger = 1;
sarahmarshy 0:1713cdc51510 77 timeout.attach(callback(this, &Sonar::trigger_toggle), 10.0e-6);
sarahmarshy 0:1713cdc51510 78 }
sarahmarshy 0:1713cdc51510 79
sarahmarshy 0:1713cdc51510 80 /**
sarahmarshy 0:1713cdc51510 81 * Public read function that returns the scaled distance result in cm
sarahmarshy 0:1713cdc51510 82 */
sarahmarshy 0:1713cdc51510 83 float read(void) {
sarahmarshy 0:1713cdc51510 84 return distance / 58.0f;
sarahmarshy 0:1713cdc51510 85 }
sarahmarshy 0:1713cdc51510 86 };
sarahmarshy 0:1713cdc51510 87
sarahmarshy 0:1713cdc51510 88
sarahmarshy 0:1713cdc51510 89 int main() {
sarahmarshy 0:1713cdc51510 90 // Create sonar object on pins D5 and D6
sarahmarshy 0:1713cdc51510 91 Sonar sonar(D5, D6);
sarahmarshy 0:1713cdc51510 92 // Begin background thread sonar acquires
sarahmarshy 0:1713cdc51510 93 sonar.start();
sarahmarshy 0:1713cdc51510 94
sarahmarshy 0:1713cdc51510 95 while(1) {
sarahmarshy 0:1713cdc51510 96 wait(0.1f);
sarahmarshy 0:1713cdc51510 97 // Periodically print results from sonar object
sarahmarshy 0:1713cdc51510 98 printf("%f\r\n", sonar.read());
sarahmarshy 0:1713cdc51510 99 }
sarahmarshy 0:1713cdc51510 100 }