树莓派3B+使用HC-SR04超声波测距模块测量距离基于C++实现

1 篇文章 0 订阅
1 篇文章 0 订阅

前言

最近公司采购了个树莓派3B+扔给我玩,于是就…
找点空闲~
找点时间~
带着电线~
杵面包板看看~
语言嘛选择了c++,毕竟想要学习下c++,
那就开整吧!
给我也整一个
我才不会说Visual Studio支持交叉编译,直接ssh远程就执行了,省的还得拷贝到树莓派里,再编译执行啦~

开发环境

  • Visual Studio IDE 2017 15.9.11(windows版 这玩意还有linux的吗??
  • C++
  • 树莓派3B+(Raspbian系统)
  • HC-SR04
  • 导线若干
  • 面包板一块
  • 2K电阻一个
  • 1K电阻一个

原理

这东西的测距原理很简单,从A点发出声波一直到B点,B点再反弹回A点,

(B)被测量物····························(A)超声波收发装置
|
|<——————————————|发出
|——————————————>|接收
|

时间间隔=接收时间-发出时间
距离=时间间隔/2*声波速度

HC-SR04

外形实拍

1.HC-SR04模块正面

HC-SR04模块正面

2.HC-SR04模块背面

HC-SR04模块背面

HC-SR04规格

工作电压5V
工作电流15mA
最短测量距离3cm
最长测量距离4m
测量角度15°
Trigger引脚输入信号10μs(微秒) TTL脉冲
Echo引脚输出信号5v 脉冲信号

接线方式

HC-SR04有VccVddEchoTrig这四个引脚。
Vcc接5V电源
Vdd接地(GND),
Trig接到GPIO20(WiringPi:28)
Echo接到GPIO21(WiringPi:29)(树莓派gpio口只能接3v的,5v可能会烧坏板子,所以得搞个分压电路)
可以改成任意GPIO口
(っ °Д °;)っ千万别把Vdd接到5V电源上,上一块HC-SR04就这样报废了!

电路图(不会画,从隔壁借来一张吧)

图片出处:树莓派3 + HC-SR04超声波测距模块 是基于python 实现的
电路图

测距过程

  1. 先向HC-SR04的Trig脚发送高电平(持续10μs)
  2. HC-SR04的Echo脚被置为高电平
  3. 接到回声,Echo脚被置为低电平

实现的关键代码

  1. hcsr04.h
    实现类
#pragma once
#include <iostream>
#include <wiringPi.h>   
#include <iomanip>
#include "TimeUtils.h"

//定义WiringPi引脚编号
const int trig = 28;
const int echo = 29;

using namespace std;

class hcsr04
{
public:
	hcsr04();
	~hcsr04();
public:
	//初始化引脚模式等
	void static init();
	//循环执行部分
	void static loop();
	//具体实现写在这里
	void static implement();
};
  1. TimeUtils.h
    获取时间工具类
#pragma once
#include <sstream>

#ifdef _WIN32
#include <windows.h>
#else
#include <sys/time.h>
#endif  // _WIND32
// 定义64位整形
#if defined(_WIN32) && !defined(CYGWIN)
typedef __int64 int64_t;
#else 
typedef long long int64t;
#endif  // _WIN32


class TimeUtils {
public:
	//获取UTC毫秒数
	static int64_t getCurrentTime();
	//获取UTC微秒(μs)
	static int64_t getSysTimeMicros();
};
  1. TimeUtils.cpp
    时间工具类实现
#include "TimeUtils.h"
#include <iostream>

int64_t TimeUtils::getCurrentTime() {
	struct timeval tv;
	gettimeofday(&tv, NULL);    //该函数在sys/time.h头文件中
	return tv.tv_sec * 1000LL + tv.tv_usec / 1000LL;
}

// 获取系统的当前时间,单位微秒(us)
int64_t TimeUtils::getSysTimeMicros() {
#ifdef _WIN32
// 从1601年1月1日0:0:0:000到1970年1月1日0:0:0:000的时间(单位100ns)
#define EPOCHFILETIME (116444736000000000UL)
	FILETIME ft;
	LARGE_INTEGER li;
	int64_t tt = 0;
	GetSystemTimeAsFileTime(&ft);
	li.LowPart = ft.dwLowDateTime;
	li.HighPart = ft.dwHighDateTime;
	// 从1970年1月1日0:0:0:000到现在的微秒数(UTC时间)
	tt = (li.QuadPart - EPOCHFILETIME) /10;
	return tt;
#else
	timeval tv;
	gettimeofday(&tv, 0);
	return (int64_t)tv.tv_sec * 1000000 + (int64_t)tv.tv_usec;
#endif // _WIN32
	return 0;
}
  1. hcsr04.cpp
    测距具体实现
#include "hcsr04.h"

hcsr04::hcsr04(){}

hcsr04::~hcsr04(){}

void hcsr04::init() {
	if (-1 == wiringPiSetup())
	{
		cerr << "setup error\n";
		exit(-1);
	}
	pinMode(trig, OUTPUT);
	pinMode(echo, INPUT);
}

void hcsr04::loop() {
	init();
	while (true)
	{
		implement();
		delay(2000);
	}
}

void hcsr04::implement() {
	//发送trig信号,持续10us 的方波脉冲
	digitalWrite(trig, HIGH);
	//接收的参数单位为 s ,于是把10 us 转换为 0.00001 s 。
	delay(0.00001);
	//关闭高电平输出
	digitalWrite(trig, LOW);
	//定义开始时间和结束时间
	int64_t start, ends;

	//等待回声低电平结束(变为高电平时继续执行)
	while (digitalRead(echo) == 0){}

	//开始计时(从1970年到当前微秒μs数)
	start = TimeUtils::getSysTimeMicros();

	//等待回声高电平结束(变为低电平时继续执行)
	while (digitalRead(echo) == 1){}
	//结束计时(从1970年到当前微秒μs数)
	ends = TimeUtils::getSysTimeMicros();

	//实际毫秒差值(从发出声音到接到回声)
	long duration = ends - start;
	//声速=343m/s
	//(结束时间-开始时间)*声波速度/2*1000···
	//(结束时间-开始时间)*17150
	//long distance = duration * 17150LL;
	//
	//厘米
	//double speed = 343 * 10;
	//米

	cout << "总程时间:" << fixed << setprecision(6) << duration << "微秒(μs)\t\t";

	//单次毫秒数
	double distance = duration / 2.0;

	cout << "半程时间:" << fixed << setprecision(6) << distance << "微秒(μs)\t\t";

	//精确到毫米
	distance = distance * 343.0;

	cout << "测算距离为:" << fixed << setprecision(6) << distance << "微米(um)\t\t";

	//得出距离(毫米)
	distance = distance / 1000.0;
	cout << fixed << setprecision(6) << distance << "毫米(mm)\t\t";

	//得出距离(厘米) 
	distance = distance / 10.0;
	cout << fixed << setprecision(6) << distance << "厘米\t\t";

	//得出距离(米)
	distance = distance / 100.0;
	cout << fixed << setprecision(6) << distance << "米" << endl;
}
  1. main.cpp
    主函数
//#include "led.h"
#include "hcsr04.h"

int main()
{
	//led::loop();
	hcsr04::loop();
	return 0;
}

运行结果

参考文档

1.树莓派wiringPi库详解
2.树莓派3 + HC-SR04超声波测距模块
3.在VS2017中编译和调试树莓派程序(wiringPi)
4.Vs2017 控制台 中文输出是乱码的问题解决

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值