【Arduino】实现超声波测距,性能稳定且测度距离精确
由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量,如测距仪和物位测量仪等都可以通过超声波来实现。利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制,并且在测量精度方面能达到工业实用的要求,因此在移动机器人研制上也得到了广泛的应用。
我们今天来学习一下超声波(HC-SR04)模块,超声波是频率很高的声音,其频率超出人类可以听到的声音的频率范围。超声波传感器发出的超声波脉冲频率是42kHz,人类平均可听到的频率上限是20kHz
HC-SR04模块性能稳定,测度距离精确,模块高精度,盲区小。多应用于机器人避障;物体测距;公共安防;停车场车位检测等领域。
工作原理:当一个控制口发一个至少10US以上的高电平,就会触发SR04的测距功能,触发后,模块会自动发送8个40KHZ的超声波脉冲,并且自动检测是否有信号返回。这一步骤会有模块内部自动完成。另一个控制口高电平持续的时间就是此次测距的时间,方可算出距离.如此不断的周期测,即可以达到你移动测量的值.
实验所用的代码如下:
/***********************************************************
File name: _36_UltrasonicDistanceSensorModule.ino
Description: When you move the obstacle in front of the
ultrasonic module,you can see the data on
the serial montiol.
Website: www.adeept.com
E-mail: support@adeept.com
Author: Tom
Date: 2017/03/18
***********************************************************/
const int pingPin = 5; // pin connected to Echo Pin in the ultrasonic distance sensor
const int trigPin = 6; // pin connected to trig Pin in the ultrasonic distance sensor
const int stbPin = 7; //the segment display module STB pin connected to digital pin 7
const int clkPin = 9; //the segment display module CLK pin connected to digital pin 9
const int dioPin = 8; //the segment display module DIO pin connected to digital pin 8
void sendCommand(uint8_t value)
{
digitalWrite(stbPin, LOW); //pin low. To begin receiving data
shiftOut(dioPin, clkPin, LSBFIRST, value); //send data(value) to the segment display module
digitalWrite(stbPin, HIGH); //pin high. Stop receiving data
}
void setup()
{
pinMode(pingPin, INPUT); //Set the connection pin output mode Echo pin
pinMode(trigPin, OUTPUT);//Set the connection pin output mode trog pin
pinMode(stbPin, OUTPUT); //initialize the stbPin as an output
pinMode(clkPin, OUTPUT); //initialize the clkPin as an output
pinMode(dioPin, OUTPUT); //initialize the dioPin as an output
sendCommand(0x8f); //activate
Serial.begin(115200); //opens serial port, sets data rate to 9600 bps
}
/*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/ /*8*/ /*9*/
uint8_t digits[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f };
int ping(int pingPin)
{
// establish variables for duration of the ping,
// and the distance result in inches and centimeters:
long duration, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(5);
digitalWrite(trigPin, LOW);
duration = pulseIn(pingPin, HIGH);
// convert the time into a distance
cm = microsecondsToCentimeters(duration);
return cm ;
}
long microsecondsToCentimeters(long microseconds)
{
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the
// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
void loop()
{
int cm = ping(pingPin);
Serial.print("distance: "); // Print a message of "Temp: "to the serial montiol.
Serial.print(cm); // Print a centigrade temperature to the serial montiol.
Serial.println(" cm"); // Print the unit of the centigrade temperature to the serial montiol.
sendCommand(0x40); //setting the Write Data Command,using automatic address genuine.
digitalWrite(stbPin, LOW); //pin low. To begin receiving data
shiftOut(dioPin, clkPin, LSBFIRST, 0xc0); //Set the start address 0C0H
if(cm >= 1000 )
{
shiftOut(dioPin, clkPin, LSBFIRST, digits[cm/1000%10]);//thousand data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[cm/100%10]); //hundred data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[cm/10%10]); //ten data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[cm%10]); //bit data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
}
else if(cm >= 100 && cm <=1000)
{
shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[cm/100%10]); //hundred data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[cm/10%10]); //ten data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[cm%10]); //bit data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
}
else if(cm >= 10 && cm <=100)
{
shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //hundred data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[cm/10%10]); //ten data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[cm%10]); //bit data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
}
else if(cm > 0 && cm <=10)
{
shiftOut(dioPin, clkPin, LSBFIRST, digits[0]);//thousand data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //hundred data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[0]); //ten data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
shiftOut(dioPin, clkPin, LSBFIRST, digits[cm%10]); //bit data
shiftOut(dioPin, clkPin, LSBFIRST, 0x00); //filling high 8-bit data
}
digitalWrite(stbPin, HIGH); //pin high. Stop receiving data
delay(500);
}