在Arduino上使用传感器:创建一个可以检测运动并作出响应的简单设备
超声波传感器是一种简洁的多功能传感器,可以应用到您的Arduino项目中。顾名思义,它利用超声波来检测出现的物体以及物体的距离。这种设备可用于动作识别,或者在检测范围内出现目标对象时作出响应。
adsensor1.jpg
当然,您也许会想知道的是Arduino超声波传感器究竟是如何工作的?
为了描述它的工作原理,本指南将向您展示如何使用超声波传感器来组装一个简单的乐器。
我们今天要了解的超声波传感器是HC-SR05, 它是旧版HC-SR04的5引脚升级版本。该设备具有两个圆柱形模块。一个是发出超声波信号的发射器,另一个是接收器,会捕获到达物体后反弹回来的信号。通过测量信号返回的时间,传感器可以计算出物体的距离。
虽然其他传感器(如被动红外线运动传感器)也具有类似的功能,但是超声波传感器的功用更强,因为它使您的项目不仅可以检测到面前经过的物体,还可以区分出不同物体的距离远近。
我们使用这种技术来创建一个浮动的乐器。该项目不是通过按下钢琴键来弹奏音符,而是让您把一个物体—比如一根棍子或者您的手指—放在传感器前面,根据物体与传感器之间的距离来播放不同的音符。这并不能打造出钢琴的效果,但是通过创建该项目,您可以了解能用这款便利的Arduino声音传感器来做什么。

所需组件
为了创建该项目,您需要具备以下组件:
Arduino Uno adsensor2.png
HC-SR05 超声波传感器(可以使用HC-SR04或其他超声波传感器,但需要修改引脚配置)
adsensor3.png
Arduino IDE adsensor4.png
您还需要使用以下硬件,都是比较通用的设备:
扬声器: 大多数简单的扬声器模块都可以,本项目使用的是该款简单的单声道扬声器。
USB 电缆
如果您还没有设置Arduino IDE,可以先查阅我们之前发布的指南。

代码
首先,我们先来看一下要上传到Arduino Uno的代码,了解将要执行的操作。
  1. void setup() {
  2. pinMode (6,OUTPUT); //Insert HC-SR-05 with VCC in pin 6
  3. pinMode (5, INPUT); // Assign pin 5 to Echo
  4. pinMode (4, OUTPUT);// Assign pin 4 to Trig
  5. pinMode (2,OUTPUT); // Assign pin 2 to GND.
  6. Serial.begin(9600); // This will allow you to read how far away your sensor is later
  7. }
  8. void loop()
  9. {
  10. long duration, cm; // Initialize variables for duration and cm
  11. digitalWrite(6, HIGH); // Power the sensor
  12. digitalWrite(4, LOW); // Clear pulse before sending a 10 microsecond ping,
  13. delayMicroseconds(2);
  14. digitalWrite(4, HIGH);
  15. delayMicroseconds(10);
  16. digitalWrite(4, LOW);
  17. duration = pulseIn(5, HIGH); // Detect pulse length from the Echo pin, measured in microseconds
  18. cm = (duration/2)/29.155; // Divide duration in half (due to round trip), then convert distance to centimeters (1cm per 29.155 microseconds), assign to cm variable
  19. Serial.print(cm); // Print distance in cm to serial monitor
  20. Serial.print(“cm”);
  21. Serial.println();
  22. delay(100); // Delay
  23. int note = 0; // Assign note based on distance, spacing notes per 6cm
  24. if(cm<=48&&cm>42) {
  25. note = 523;
  26. } else if(cm<=42&&cm>36) {
  27. note = 493;
  28. } else if(cm<=36&&cm>30) {
  29. note = 440;
  30. } else if(cm<=30&&cm>24) {
  31. note = 392;
  32. } else if(cm<=24&&cm>18) {
  33. note = 349;
  34. } else if(cm<=18&&cm>12) {
  35. note = 329;
  36. } else if(cm<=12&&cm>6) {
  37. note = 294;
  38. } else if(cm<=6) {
  39. note = 261;
  40. }
  41. if (note == 0) { // If distance isn’t within 48cm, play nothing
  42. noTone(9);
  43. } else {
  44. tone(9, note, 200); // Play assigned note for 200 milliseconds
  45. }
  46. delay(10); // Brief pause
  47. }
您可以将上述代码复制到您的IDE中,将其上传到Uno,如果您想运行该代码,可以继续进行下一部分,但是这部分的代码很重要,有必要对其进行分析和理解。首先:
  1. digitalWrite(6, HIGH); // Power the sensor
  2. digitalWrite(4, LOW); // Clear pulse before sending a 10 microsecond ping,
  3. delayMicroseconds(2);
  4. digitalWrite(4, HIGH);
  5. delayMicroseconds(10);
  6. digitalWrite(4, LOW);
  7. duration = pulseIn(5, HIGH); // Detect pulse length from the Echo pin, measured in microseconds
  8. cm = (duration/2)/29.155; // Divide duration in half (due to round trip), then convert distance to centimeters (1cm per 29.155 microseconds), assign to cm variable
这部分的操作是在Trig引脚上发出40KHz脉冲。这种超声波信号会在它接触的所有物体上发生反射,然后返回到接收器。
接下来,pulseIn() 函数测量从脉冲离开传感器到接收器检测到返回信号所用的时间,单位为微秒。
然后将该时间除以2,因为这是信号往返花费的总时间。这为我们提供了40KHz声音传播到物体所需的微秒数。由于声音传播1厘米大约需要29.155微秒,所以我们可以将计算出的时间除以29.155。以此我们就可以计算出目标对象的距离,单位为厘米,然后将该距离值分配给cm变量。
接下来的几行代码会将距离(以厘米为单位)打印到串行监视器,这有助于确认代码运行正常,并便于我们在运行程序时查看物体的距离。
代码的最后主要相关部分是这样的:
  1. int note = 0; // Assign note based on distance, spacing notes per 6cm
  2. if(cm<=48&&cm>42) {
  3. note = 523;
  4. } else if(cm<=42&&cm>36) {
  5. note = 493;
  6. } else if(cm<=36&&cm>30) {
  7. note = 440;
  8. } else if(cm<=30&&cm>24) {
  9. note = 392;
  10. } else if(cm<=24&&cm>18) {
  11. note = 349;
  12. } else if(cm<=18&&cm>12) {
  13. note = 329;
  14. } else if(cm<=12&&cm>6) {
  15. note = 294;
  16. } else if(cm<=6) {
  17. note = 261;
  18. }
  19. if (note == 0) { // If distance isn’t within 48cm, play nothing
  20. noTone(9);
  21. } else {
  22. tone(9, note, 200); // Play assigned note for 200 milliseconds
  23. }
该代码块将根据物体的距离为扬声器分配一个频率。 此Arduino参考文档 列出了一系列音符的频率,我们将以此作为参考。 使用 if else 语句 来根据目标对象的距离(以6cm为增量)为音符变量分配一个频率,可在整个八度音阶范围内提供八个音符。如果没有检测到任何物体,音符变量值为0。
在最后一部分中,tone() 函数 用来播放音符,如果48cm内没有检测到物体,noTone()函数 将会停止前一个声音的播放。在开始循环之前的最后一个指令是delay()。这些延迟有助于避免程序更改音符过快,因为传感器的精确度没有那么高。
adsensor5.jpg

接线
了解了代码如何运行之后,您就可以将其上传到Arduino Uno上了,然后拔掉设备。现在,是时候将它们连接起来了。我们已经完成了代码的编写以尽可能简化该过程。您所要做的就是按照以下步骤进行操作:
● 将HC-SR05传感器插入数字引脚2到6,GND插入引脚2,VCC插入引脚6。这样连接可以使传感器朝向外侧,远离Arduino。
● 将扬声器上的正极线(通常为红色)插入引脚9。
● 将另一根扬声器线(通常为黑色)插入其中一个GND引脚。
连接好所有电线好,插入Arduino,并在传感器前留出大约50厘米的空间。接下来是最有趣的部分。将您的手或者一根小棍子放在传感器前面,您会听到扬声器发出的声音。物体放置的越远,音调越高。
您可以尝试使用delay()tone()所带来的持续时间使声音听起来更平滑,或调整频率值以获得不同的音符。该传感器还可以用作报警器,以在物体进入一定范围内的区域时发出警报,或者当您的手处于某一距离范围内时向您的计算机发送指令。


来源:techclass.rohm