HC-SR04 raspberry pi
HC - SR04 raspberry pi
我有 raspberry pi b,我正在尝试用 C 编写代码,以允许我使用 HC-SR04 Ultrasonic Ranging Module. I used the bcm2835 library to control the GPIO pins. I have connected it according to this website。这是我的尝试:
# 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;
}
存在两个问题:
- 我的读取时间的方法最多只能准确到 1 秒,- 然而,当我寻找更好的方法时,我发现了两种方法,但没有明确的答案,哪一种实际上更好 (clock_gettime( ) 或 gettimeofday())。
- 即使指向很远的地方,循环也几乎立即完成,导致两个 time() 调用的值完全相同。这可能是由于我获取当前时间的糟糕方法,但我不确定。
我很确定我在这里遗漏了一些明显的东西,但我需要帮助才能找到它。
编辑:更好的解决方案是使用 GPIO 中断来计时回声间隔
一个建议(必须是评论,但我没有足够的声誉)
使用 gettimeofday() 而不是 time() -- 它提供了更高的时间分辨率。
此外,我会这样更改 while 循环:
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);
这是我在我的博客上制作的教程,用于从 Raspberry Pi 上的 C++ 中的 HC-SR04 获取值!
你可能想看一看:
https://causeyourestuck.io/2016/04/15/hc-sr04-raspberry-pi-c/
最后看起来像这样:
Sonar sonar;
sonar.init(trigger, echo);
while(1){
cout << "Distance is " << sonar.distance(30000) << " cm." << endl; // 30000 is a timeout in microseconds
}
我有 raspberry pi b,我正在尝试用 C 编写代码,以允许我使用 HC-SR04 Ultrasonic Ranging Module. I used the bcm2835 library to control the GPIO pins. I have connected it according to this website。这是我的尝试:
# 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;
}
存在两个问题:
- 我的读取时间的方法最多只能准确到 1 秒,- 然而,当我寻找更好的方法时,我发现了两种方法,但没有明确的答案,哪一种实际上更好 (clock_gettime( ) 或 gettimeofday())。
- 即使指向很远的地方,循环也几乎立即完成,导致两个 time() 调用的值完全相同。这可能是由于我获取当前时间的糟糕方法,但我不确定。
我很确定我在这里遗漏了一些明显的东西,但我需要帮助才能找到它。
编辑:更好的解决方案是使用 GPIO 中断来计时回声间隔
一个建议(必须是评论,但我没有足够的声誉)
使用 gettimeofday() 而不是 time() -- 它提供了更高的时间分辨率。
此外,我会这样更改 while 循环:
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);
这是我在我的博客上制作的教程,用于从 Raspberry Pi 上的 C++ 中的 HC-SR04 获取值!
你可能想看一看:
https://causeyourestuck.io/2016/04/15/hc-sr04-raspberry-pi-c/
最后看起来像这样:
Sonar sonar;
sonar.init(trigger, echo);
while(1){
cout << "Distance is " << sonar.distance(30000) << " cm." << endl; // 30000 is a timeout in microseconds
}