×

超声波传感器测量距离计算实例

消耗积分:2 | 格式:zip | 大小:0.82 MB | 2023-07-07

杨海清

分享资料个

描述

该项目将向您展示如何使用超声波传感器计算距离。它将分为三个部分:

  • 编程超声波传感器 + 将其显示到串行监视器上
  • 如何在 LCD 上显示距离
  • 将中断与超声波传感器结合使用

编程超声波传感器 + 将其显示到串行监视器上:

在本节结束时,您的项目应如下所示:

 

如您所见,当我移动手时,距离会发生变化。当我将手移开时,距离也会发生变化——它会增加。当我将手移近传感器时,距离会缩短。您可能已经注意到,有时距离是一个 3 位数。这是因为我的手离传感器太近了。发送的声波迅速反弹,供传感器读取。

示意图:

 

 
pYYBAGOSwz6AAH9WAAFG9K78nf8729.png
4 针接头代表超声波传感器。
 

 

连接到 Gnd 的电线是传感器上的“Gnd”脚,连接到引脚号的电线。9,是“回声”腿,连接到引脚号的电线。10 是“Trig”脚,连接到 5v 的电线是“Vcc”脚。

编码:

首先,将其添加到代码的开头。

// defines pins numbers
const int trigPin = 9;
const int echoPin = 10; 

其次,我们需要定义变量。

long duration;
int distance; 

void setup()函数中,我们需要声明每个引脚的输入/输出。我们还需要启动串行通信。

void setup() {
 pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
 pinMode(echoPin, INPUT); // Sets the echoPin as an Input
 Serial.begin(9600); // Starts the serial communication
}

现在,对于void loop()函数,添加以下内容:

 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);

此代码清除 trigPin。然后,要将引脚设置为高电平 10 微秒,请添加:

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);

接下来,编写以下内容:

 duration = pulseIn(echoPin, HIGH);

此行读取 echoPin,以微秒为单位返回声波传播时间。

最后,要计算距离并将其打印到您的串行监视器上,请将其写入您的代码。

 distance = duration * 0.034 / 2;
 Serial.print("Distance: ");
 Serial.println(distance);
 delay(10);

您的代码应类似于以下内容:

// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;
// defines variables
long duration;
int distance;
void setup() {
 pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
 pinMode(echoPin, INPUT); // Sets the echoPin as an Input
 Serial.begin(9600); // Starts the serial communication
}
void loop() {
 // Clears the trigPin
 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);
 // Sets the trigPin on HIGH state for 10 micro seconds
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);
 // Reads the echoPin, returns the sound wave travel time in microseconds
 duration = pulseIn(echoPin, HIGH);
 // Calculating the distance
 distance = duration * 0.034 / 2;
 // Prints the distance on the Serial Monitor
 Serial.print("Distance: ");
 Serial.println(distance);
 delay(10);
} 

如果您的代码有效,那就太好了。但如果没有,那么您可能需要检查以下内容:

  • 电路接线是否正确。
  • 你是否有相同的串口和串口连接(9600)。
  • 如果您的超声波传感器工作正常。

如何在 LCD 上显示距离

现在,我们不再将距离显示在串行监视器上,而是将其显示在 LCD 上。最后,您的项目应如下所示:

 

示意图:

 
pYYBAGOSw0OAE5Z3AAE0QY2DZI4826.png
LCD 的布线令人困惑但很重要。
 

 

 

编码:

现在,将其添加到代码的开头。

#include <LiquidCrystal.h> // includes the LiquidCrystal Library 
LiquidCrystal lcd(

要显示 2 种不同类型的距离,请将“ int distance”更改为以下内容:

int distanceCm, distanceInch;

这意味着 LCD 将以厘米和英寸为单位显示距离。接下来,在void setup()函数中添加:

lcd.begin(16,2); 

另外,删除serial.begin()函数,因为我们不需要与 CPU 通信。现在,要计算以英寸为单位的距离,我们需要添加以下代码。

distanceInch = duration * 0.0113 / 2; /*remember to change the 'distance' variable 
                                        into distanceCm*/

添加此代码以将距离打印到 LCD 上。

 lcd.setCursor(0,0); 
 lcd.print("Distance: "); 
 lcd.print(distanceCm); 
 lcd.print("cm   ");
 delay(10);
 lcd.setCursor(0,1);
 lcd.print("Distance: ");
 lcd.print(distanceInch);
 lcd.print("inch ");
 delay(10);

在此代码中,光标设置为 LCD 上的第 0 行、第 0 列。然后,将显示“距离:”一词,在其旁边,LCD 上将打印以厘米为单位的距离。与以英寸为单位的距离相同,但将向下一行。您的代码应如下所示:

#include 
LiquidCrystal lcd(1,3,4,5,6,7);
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;
// defines variables
long duration;
int distanceCm, distanceInch;
void setup() {
 lcd.begin(16,2);
 pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
 pinMode(echoPin, INPUT); // Sets the echoPin as an Input
}
void loop() {
 // Clears the trigPin
 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distanceCm = duration * 0.034 / 2;
 distanceInch = duration * 0.0113 / 2;
 lcd.setCursor(0,0); 
 lcd.print("Distance: "); 
 lcd.print(distanceCm); 
 lcd.print("cm   ");
 delay(10);
 lcd.setCursor(0,1);
 lcd.print("Distance: ");
 lcd.print(distanceInch);
 lcd.print("inch ");
 delay(10);
} 

  • 检查您的代码是否正确。
  • 检查您的电路和 LCD 接线是否正确。

将中断与超声波传感器结合使用:

在项目的这一部分中,您将使用中断来控制传感器何时测量距离。它应该是这样的:

 

您可能已经注意到,当我按下按钮时,LCD 上的距离会发生变化。这是因为超声波传感器仅在按下按钮时检查距离。

示意图:

 

 
pYYBAGOhWtaARbfIAAH1kKZWszc763.png
 

我将按钮连接到 Arduino 板上的 2 号引脚,因为它和 3 号引脚是唯一可以使用 interrupt() 函数的引脚。

更新(08/08/2018)Interrupt()函数实际上可用于引脚 18、19、20 和 21 以及引脚 2 和 3。感谢 Walter Stroebel 指出这一点。

编码:

首先,我们需要说明按钮所连接的引脚,因此将其添加到代码的开头。

const int buttonPin = 2;

然后,要添加interrupt()函数,请将此行添加到void setup()函数中。

 attachInterrupt(digitalPinToInterrupt(buttonPin), pin_ISR, FALLING);

我们现在要做的就是从void loop()函数中获取所有内容并将其添加到另一个函数中,这个函数称为pin_ISR() 最后,您的代码应如下所示:

#include 
LiquidCrystal lcd(1,3,4,5,6,7);
// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;
const int buttonPin = 2;
// defines variables
long duration;
int distanceCm, distanceInch;
void setup() {
 lcd.begin(16,2);
 pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
 pinMode(echoPin, INPUT); // Sets the echoPin as an Input
 pinMode(buttonPin, INPUT);
 attachInterrupt(digitalPinToInterrupt(buttonPin), pin_ISR, FALLING);
}
void loop() {
}
void pin_ISR(){
 // Clears the trigPin
 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distanceCm = duration * 0.034 / 2;
 distanceInch = duration * 0.0113 / 2;
 lcd.setCursor(0,0); 
 lcd.print("Distance: "); 
 lcd.print(distanceCm); 
 lcd.print("cm   ");
 delay(10);
 lcd.setCursor(0,1);
 lcd.print("Distance: ");
 lcd.print(distanceInch);
 lcd.print("inch ");
 delay(10);
}

更新(08/08/2018)Walter Stroebel 发表评论,将当前代码改进为以下内容:

#include 
LiquidCrystal lcd(1,3,4,5,6,7);
// defines pins numbers
volatile bool buttonPressed = false;
const int trigPin = 9;
const int echoPin = 10;
const int buttonPin = 2;
// defines variables
long duration;
int distanceCm, distanceInch;
void setup() {
 lcd.begin(16,2);
 pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
 pinMode(echoPin, INPUT); // Sets the echoPin as an Input
 pinMode(buttonPin, INPUT);
 attachInterrupt(digitalPinToInterrupt(buttonPin), pin_ISR, FALLING);
}
void loop() {
 if (buttonPressed) {
 // Clears the trigPin
 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distanceCm = duration * 0.034 / 2;
 distanceInch = duration * 0.0113 / 2;
 lcd.setCursor(0,0); 
 lcd.print("Distance: "); 
 lcd.print(distanceCm); 
 lcd.print("cm   ");
 delay(10);
 lcd.setCursor(0,1);
 lcd.print("Distance: ");
 lcd.print(distanceInch);
 lcd.print("inch ");
 delay(10);
 buttonPressed = false;
 }
}
void pin_ISR(){
 buttonPressed = true;
}
// I would like to thank Walter Stroebel for suggesting this code.

这段代码更好,因为它更短意味着中断将更好地工作并且可以同时使用更多。

如果您的代码不起作用,请检查以下内容:

  • 如果您已正确连接 LCD、按钮和传感器。
  • 如果你的代码写对了。

希望你玩得开心。祝未来的项目好运!


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.lene-v.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'超声波传感器测量距离计算实例',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.lene-v.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);