前言
最近公司采购了个树莓派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模块正面
2.HC-SR04模块背面
HC-SR04规格
工作电压 | 5V |
---|---|
工作电流 | 15mA |
最短测量距离 | 3cm |
最长测量距离 | 4m |
测量角度 | 15° |
Trigger引脚输入信号 | 10μs(微秒) TTL脉冲 |
Echo引脚输出信号 | 5v 脉冲信号 |
接线方式
HC-SR04有Vcc
,Vdd
,Echo
,Trig
这四个引脚。
Vcc
接5V电源
Vdd
接地(GND),
Trig
接到GPIO20(WiringPi:28)
Echo
接到GPIO21(WiringPi:29)(树莓派gpio口只能接3v的,5v可能会烧坏板子,所以得搞个分压电路)
可以改成任意GPIO口
(っ °Д °;)っ千万别把Vdd接到5V电源上,上一块HC-SR04就这样报废了!
电路图(不会画,从隔壁借来一张吧)
图片出处:树莓派3 + HC-SR04超声波测距模块 是基于python 实现的
测距过程
- 先向HC-SR04的Trig脚发送高电平(持续10μs)
- HC-SR04的Echo脚被置为高电平
- 接到回声,Echo脚被置为低电平
实现的关键代码
- 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();
};
- 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();
};
- 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;
}
- 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;
}
- 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 控制台 中文输出是乱码的问题解决