百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

树莓派Python/C语言超声波测距以及利用超声波模块小车避障

liebian365 2024-10-30 04:48 37 浏览 0 评论

使用Python进行超声距离测量 - 第1部分

  • 超声波传感器

LED,蜂鸣器和开关是人们尝试与Raspberry Pi相连接的最常见的项目。在某宝中发现的有点不同的是超声波测量模块。这允许您测量距离最近的墙壁或固体物体的距离。这些模块很容易买到,便宜而且比较直接的连接到GPIO头。

所以这里有一些关于我的超声测量模块和Python的实验的信息。在未来的项目中,我可以看到这些模块是向Pi动力机器人或汽车添加一些智能的好方法。

HC-SR04模块的成本约为3-4yuan,是一个匹配的大小。其设计由5V供电,具有1个输入引脚和1个输出引脚。该模块通过向空中发送超声波脉冲并测量反弹所需的时间来工作。该值可以用于计算脉冲行进的距离。

连接到Pi

为模块供电很简单。只需将+ 5V和Ground引脚连接到Pi的GPIO接头上的引脚2和引脚6。

模块上的输入引脚称为“触发”,用于触发发送超声波脉冲。理想情况下,它需要一个5V信号,但它与GPIO的3.3V信号工作正常。所以我将触发器直接连接到GPIO头上的引脚16(GPIO23)。

您可以在RPI上使用任何您喜欢的GPIO引脚,但您需要注意引用并相应地修改您的Python脚本。

模块的输出称为“回波”,需要更多思考。输出引脚为低电平(0V),直到模块进行距离测量。然后将此引脚设置为高电平(+ 5V),使脉冲返回相同的时间。所以我们的脚本需要衡量这个引脚保持高电平的时间。该模块对“高”使用+ 5V电平,但是对于仅适用于3.3V的GPIO头上的输入,该模块太高。为了确保Pi只能用3.3V命中,我们可以使用基本的分压器。这是由两个电阻组成。

如果R1和R2相同,则电压被分成两半。这将给我们2.5V。如果R2是R1的两倍,那么我们得到3.33V,这是很好的。所以理想情况下,您希望R2位于R1和R1 x2之间。在我的示例电路中,我使用了330和470欧姆的电阻。一个替代方案是使用1K和1K5值。如果不用也可以 ,但不保证不bug

这是我的最后一个电路图。我选择了GPIO23和GPIO24,但您可以使用GPIO头上的17个可用GPIO引脚中的任何一个。只要记住更新脚本。

超声波模块电路

这是我的电路照片。我用了一小块面包板和一些男对女跳线。

超声波传感器电路

Python脚本

现在脚本实际上要做一些测量。在这个例子中,我使用的是Python。为什么Python?这是Pi最喜欢的语言,所以我倾向于将它用于所有的实验,但是这里的技术很容易应用于C.

您可以直接使用此链接 或通过Pi上的命令行下载脚本:

wget https://bitbucket.org/MattHawkinsUK/rpispy-misc/raw/master/python/ultrasonic_1.py

然后可以使用以下命令运行:

sudo python ultrasonic_1.py

声音的速度

用于找到距离的计算依赖于声音的速度。这随温度而变化。脚本根据预定义的温度计算要使用的正确值。如果需要,您可以更改此值,或者使用温度传感器动态测量该值。

相片

以下是我通过GPIO头连接到Raspberry Pi的超声波传感器的一些照片:

准确性

这里有一些关于准确性的一些观点:

  • 距离测量的精度取决于时间。Linux下的Python不适合精确的时序,但是对于一般的操作,它可以正常工作。为了提高准确性,您需要开始使用C代替。

  • 当配置GPIO时,模块需要一段时间才能完成第一次读取,所以我在脚本开始时添加了0.5秒的延迟。

  • 传感器具有广泛的灵敏度。在杂乱的环境中,由于对象在模块的侧面,您可能会读取更短的读数。

  • 测量时间可达2厘米左右。低于这个限度,结果可以给出奇怪的结果。

  • 如果超声波传感器接触任何东西,结果是不可预知的。

感谢这项技术,我现在知道从我的桌子到天花板的距离是155厘米。

如果不用上面的代码 可以复制如下代码进行测试。我是在树莓派3B上运行

#! /usr/bin/python

# -*- coding:utf-8 -*-

#本代码实现的是树莓派利用超声波模块测距

#使用超声波测距模块时,VCC接树莓派的5V,GND接树莓派GND。trig接树莓派38,echo接树莓派40.

#GPIO编码方式为BOARD!!!

import RPi.GPIO as GPIO

import time

def checkdist():

#发出触发信号

GPIO.output(38,GPIO.HIGH)

#保持10us以上(我选择15us)

time.sleep(0.000015)

GPIO.output(38,GPIO.LOW)

while not GPIO.input(40):

pass

#发现高电平时开时计时

t1 = time.time()

while GPIO.input(40):

pass

#高电平结束停止计时

t2 = time.time()

#返回距离,单位为厘米

return (t2-t1)*34000/2

GPIO.setmode(GPIO.BOARD)

GPIO.setup(38,GPIO.OUT,initial=GPIO.LOW)

GPIO.setup(40,GPIO.IN)

time.sleep(2)

try:

while True:

print 'Distance: %0.2f cm' %checkdist()

time.sleep(0.5)

except KeyboardInterrupt:

GPIO.cleanup()

下面为小车避障的代码 ,先定义小车前后左右的动作。然后进行距离判断进行相应的动作。

#!/home/pi/server

# coding=utf-8

#使用超声波测距模块时,VCC接树莓派的5V,GND接树莓派GND。trig接树莓派38,echo接树莓派40.

#GPIO编码方式为BOARD!!

import RPi.GPIO as GPIO

import time

def t_stop():

GPIO.output(11,False)

GPIO.output(12,False)

GPIO.output(15,False)

GPIO.output(16,False)

def t_up():

GPIO.output(11,True)

GPIO.output(12,False)

GPIO.output(15,True)

GPIO.output(16,False)

def t_down():

GPIO.output(11,False)

GPIO.output(12,True)

GPIO.output(15,False)

GPIO.output(16,True)

def t_left():

GPIO.output(11,False)

GPIO.output(12,True)

GPIO.output(15,True)

GPIO.output(16,False)

def t_right():

GPIO.output(11,True)

GPIO.output(12,False)

GPIO.output(15,False)

GPIO.output(16,True)

def bee():

GPIO.output(12,True)

time.sleep(0.5)

GPIO.output(12,False)

GPIO.output(15,True)

time.sleep(5)

GPIO.output(12,True)

GPIO.output(15,False)

def checkdist():

#发出触发信号

GPIO.output(38,GPIO.HIGH)

#保持10us以上(我选择15us)

time.sleep(0.000015)

GPIO.output(38,GPIO.LOW)

while not GPIO.input(40):

pass

#发现高电平时开时计时

t1 = time.time()

while GPIO.input(40):

pass

#高电平结束停止计时

t2 = time.time()

#返回距离,单位为厘米

return (t2-t1)*34000/2

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BOARD)

GPIO.setup(38,GPIO.OUT,initial=GPIO.LOW)

GPIO.setup(40,GPIO.IN)

GPIO.setup(11,GPIO.OUT)

GPIO.setup(12,GPIO.OUT)

GPIO.setup(15,GPIO.OUT)

GPIO.setup(16,GPIO.OUT)

##time.sleep(2)

try:

while True:

dis = int(checkdistance())

print(dis)

if dis <= 30:

print"distance less than 0.30m and back"

t_stop()

time.sleep(0.1)

t_down()

time.sleep(0.5)

t_left()

elif dis > 30:

print"forward"

time.sleep(0.1)

t_up()

except KeyboardInterrupt:

GPIO.cleanup()

此图与代码中定义是C语言的代码

如下为小车超声波避障的C代码

#include <stdio.h>

#include <stdlib.h>

#include <softPwm.h>

#include <unistd.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <time.h>

#include <wiringPi.h>

#define Trig28

#define Echo29

#define BUFSIZE 512

#define MOTOR_GO_FORWARD digitalWrite(1,HIGH);digitalWrite(4,LOW); digitalWrite(5,HIGH);digitalWrite(6,LOW)

#define MOTOR_GO_BACK digitalWrite(1,LOW); digitalWrite(4,HIGH);digitalWrite(5,LOW); digitalWrite(6,HIGH)

#define MOTOR_GO_RIGHT digitalWrite(1,HIGH);digitalWrite(4,LOW); digitalWrite(5,LOW); digitalWrite(6,LOW)

#define MOTOR_GO_LEFT digitalWrite(1,LOW); digitalWrite(4,LOW); digitalWrite(5,HIGH);digitalWrite(6,LOW)

#define MOTOR_GO_STOP digitalWrite(1, LOW);digitalWrite(4,LOW); digitalWrite(5, LOW);digitalWrite(6,LOW)

void ultraInit(void)

{

pinMode(Echo, INPUT);

pinMode(Trig, OUTPUT);

}

float disMeasure(void)

{

struct timeval tv1;

struct timeval tv2;

long start, stop;

float dis;

digitalWrite(Trig, LOW);

delayMicroseconds(2);

digitalWrite(Trig, HIGH);

delayMicroseconds(10); //发出超声波脉冲

digitalWrite(Trig, LOW);

while(!(digitalRead(Echo) == 1));

gettimeofday(&tv1, NULL); //获取当前时间

while(!(digitalRead(Echo) == 0));

gettimeofday(&tv2, NULL); //获取当前时间

start = tv1.tv_sec * 1000000 + tv1.tv_usec; //微秒级的时间

stop = tv2.tv_sec * 1000000 + tv2.tv_usec;

dis = (float)(stop - start) / 1000000 * 34990 / 2; //求出距离

return dis;

}

int main(int argc, char *argv[])

{

float dis;

// char buf[BUFSIZE]={0xff,0x00,0x00,0x00,0xff};

int time=1;

/*RPI*/

wiringPiSetup();

/*WiringPi GPIO*/

pinMode (1, OUTPUT);//IN1

pinMode (4, OUTPUT);//IN2

pinMode (5, OUTPUT);//IN3

pinMode (6, OUTPUT);//IN4

printf("ok");//

while(1){

dis = disMeasure();

printf("distance = %0.2f cm\n",dis);//输出当前超声波测得的距离

if(dis<30){ //测得前方障碍的距离小于30cm时做出如下响应

MOTOR_GO_BACK;

delay(time * 300);

MOTOR_GO_LEFT;

delay(time * 300);

}

else {

MOTOR_GO_FORWARD; //无障碍时前进

delay(time * 10);

MOTOR_GO_STOP;

}

}

return 0;

}

相关推荐

精品博文嵌入式6410中蓝牙的使用

BluetoothUSB适配器拥有一个BluetoothCSR芯片组,并使用USB传输器来传输HCI数据分组。因此,LinuxUSB层、BlueZUSB传输器驱动程序以及B...

win10跟这台计算机连接的前一个usb设备工作不正常怎么办?

前几天小编闲来无事就跑到网站底下查看粉丝朋友给小编我留言询问的问题,还真的就给小编看到一个问题,那就是win10跟这台计算机连接的一个usb设备运行不正常怎么办,其实这个问题的解决方法时十分简单的,接...

制作成本上千元的键盘,厉害在哪?

这是稚晖君亲自写的开源资料!下方超长超详细教程预警!!全文导航:项目简介、项目原理说明、硬件说明、软件说明项目简介瀚文智能键盘是一把我为自己设计的——多功能、模块化机械键盘。键盘使用模块化设计。左侧的...

E-Marker芯片,USB数据线的“性能中枢”?

根据线缆行业的研究数据,在2019年搭载Type-C接口的设备出货量已达到20亿台,其中80%的笔记本电脑和台式电脑采用Type-C接口,50%的智能手机和平板电脑也使用Type-C接口。我们都知道,...

ZQWL-USBCANFD二次开发通讯协议V1.04

修订历史:1.功能介绍1.1型号说明本文档适用以下型号:  ZQWL-CAN(FD)系列产品,USB通讯采用CDC类实现,可以在PC机上虚拟出一个串口,串口参数N,8,1格式,波特率可以根据需要设置(...

win10系统无法识别usb设备怎么办(win10不能识别usb)

从驱动入手,那么win10系统无法识别usb设备怎么办呢?今天就为大家分享win10系统无法识别usb设备的解决方法。1、右键选择设备管理器,如图:  2、点击更新驱动程序,如图:  3、选择浏览...

微软七月Win8.1可选补丁有内涵,含大量修复

IT之家(www.ithome.com):微软七月Win8.1可选补丁有内涵,含大量修复昨日,微软如期为Win7、Win8.1发布7月份安全更新,累计为6枚安全补丁,分别修复总计29枚安全漏洞,其中2...

如何从零开始做一个 USB 键盘?(怎么制作usb)

分两种情况:1、做一个真正的USB键盘,这种设计基本上不涉及大量的软件编码。2、做一个模拟的USB键盘,实际上可以没有按键功能,这种的需要考虑大量的软件编码,实际上是一个单片机。第一种设计:买现成的U...

电脑识别U盘失败?5个实用小技巧,让你轻松搞定USB识别难题

电脑识别U盘失败?5个实用小技巧,让你轻松搞定USB识别难题注意:有些方法会清除USB设备里的数据,请谨慎操作,如果不想丢失数据,可以先连接到其他电脑,看能否将数据复制出来,或者用一些数据恢复软件去扫...

未知usb设备设备描述符请求失败怎么解决

出现未知daousb设备设备描述符请求失du败解决办zhi法如下:1、按下Windows+R打开【运行】;2、在版本运行的权限输入框中输入:services.msc按下回车键打开【服务】;2、在服务...

读《飘》47章20(飘每章概括)

AndAhwouldn'tleaveMissEllen'sgrandchildrenfornotrashystep-patobringup,never.Here,Ah...

英翻中 消失的过去 37(消失的英文怎么说?)

翻译(三十七):消失的过去/茱迪o皮考特VanishingActs/JodiPicoult”我能做什么?“直到听到了狄利亚轻柔的声音,我才意识到她已经在厨房里站了好一会儿了。当她说话的时候,...

RabbitMQ 延迟消息实战(rabbitmq如何保证消息不被重复消费)

现实生活中有一些场景需要延迟或在特定时间发送消息,例如智能热水器需要30分钟后打开,未支付的订单或发送短信、电子邮件和推送通知下午2:00开始的促销活动。RabbitMQ本身没有直接支持延迟...

Java对象拷贝原理剖析及最佳实践(java对象拷贝方法)

作者:宁海翔1前言对象拷贝,是我们在开发过程中,绕不开的过程,既存在于Po、Dto、Do、Vo各个表现层数据的转换,也存在于系统交互如序列化、反序列化。Java对象拷贝分为深拷贝和浅拷贝,目前常用的...

如何将 Qt 3D 渲染与 Qt Quick 2D 元素结合创建太阳系行星元素?

Qt组件推荐:QtitanRibbon:遵循MicrosoftRibbonUIParadigmforQt技术的RibbonUI组件,致力于为Windows、Linux和MacOSX提...

取消回复欢迎 发表评论: