pluczak
pluczak

Reputation: 63

HC - SR04 raspberry pi

I have raspberry pi b and I am trying to write code in C that will allow me to use the HC-SR04 Ultrasonic Ranging Module. I used the bcm2835 library to control the GPIO pins. I have connected it according to this website. Here is my attempt:

# include <bcm2835.h>
# include <stdio.h>
# include <time.h>
# include <stdlib.h>

# define ECHO RPI_V2_GPIO_P1_03
# define TRIG RPI_V2_GPIO_P1_05

int main(int argc, char **argv) {
if (!bcm2835_init())
    return 1;

bcm2835_gpio_fsel(ECHO, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_fsel(TRIG, BCM2835_GPIO_FSEL_OUTP);

time_t clockstart = 0;
time_t clockstop = 0;

bcm2835_gpio_write(ECHO, LOW);
delay(2);

printf("trigger\n");

bcm2835_gpio_write(TRIG, HIGH);
usleep(10);
bcm2835_gpio_write(TRIG, LOW);

printf("measure\n");


while (bcm2835_gpio_lev(ECHO) == 0) {
    clockstart = time(NULL);
}

printf("B: %i\n", (int)clockstart);

while (bcm2835_gpio_lev(ECHO) == 1) {
    clockstop = time(NULL);
}

printf("E: %i\n", (int)clockstop);

time_t delta = clockstop - clockstart;

printf("D: %i\n", delta);

double distance = (delta * 340) / 2;

printf("DISTANCE: %i\n", distance);

bcm2835_close();
return 0;
}

Two problems exist:

  1. My method for reading time is accurate only up to 1 sec,- however as I looked for a better way of doing this I found two methods and no definitive answer which one is actually better (clock_gettime() or gettimeofday()).
  2. Even when pointed very far away, the loops finish almost instantaneously leading to the exact same value of both time() calls. This could be due to my crappy method of getting current time, but I"m not sure.

I'm pretty sure I'm missing something obvious here, but I need help finding it.

Upvotes: 2

Views: 3046

Answers (2)

Rapha&#235;l Vig&#233;e
Rapha&#235;l Vig&#233;e

Reputation: 2045

This is a tutorial I made on my blog, to get values from the HC-SR04 in C++ on Raspberry Pi!

You may want to take a look at it:

https://causeyourestuck.io/2016/04/15/hc-sr04-raspberry-pi-c/

At the end it look like this:

Sonar sonar;
sonar.init(trigger, echo);

while(1){
    cout << "Distance is " << sonar.distance(30000) << " cm." << endl; // 30000 is a timeout in microseconds
}

Upvotes: 0

Landon Donovan
Landon Donovan

Reputation: 34

EDIT: A better solution would be to use GPIO interrupts to time the echo interval

One suggestion (must really be a comment, but I don't have enough reputation)

Use gettimeofday() instead of time() -- it provides a greater resolution in timing.

Also, I'd change the while loops this way:

struct timeval start, end;

while (!bcm2835_gpio_lev(ECHO));   // Although gcc may be smart
gettimeofday(&start, NULL);        // enough to do this optimisation
while (bcm2835_gpio_lev(ECHO));    // on its own
gettimeofday(&end, NULL);

double delta = (end.tv_sec - start.tv_sec) * 1000.0;     // s to ms
       delta += (end.tv_usec - start.tv_usec) / 1000.0;  // us to ms

printf("D: %f ms\n", delta);

Upvotes: 1

Related Questions