转载

Windows 10 IoT开发:HC-04超声波传感器测距(树莓派3)

HC-04是树莓派上用的比较广泛的超声波传感器,可以用来测量设备和物体之间的距离。可惜网上的资料很少有针对Windows 10的,几乎都是Python和C在Linux上的例子。

hackster.io上有 一篇用HC-04做雷达的例子 ,但是设计的部件太多了,对单纯学习HC-04传感器的使用来说这个例子比较复杂。搜了一圈,英文资料最好的是这篇: http://www.guruumeditation.net/en/digital-io-with-windows-10-iot-raspberry-pi-2-and-the-ultrasonic-ranging-module-hc-sr04/ 国内中文资料介绍Windows 10上HC-04传感器的文章似乎还没有,所以就简单总结一下步骤。

对于没有多少物理和电子知识基础的人(比如我)来说,第一步连线是比较难的。很多文章都一笔带过说“这很简单,没啥好说的”,尼玛。。。

其实要解决的问题是这样的:HC-04需要接入5V电源才能工作,它的响应输出是ECHO,这个要接到树莓派的GPIO端口上使用,但是ECHO的输出是5V,GPIO只能接受3.3V左右的输入,5V会烧掉树莓派,所以必须加电阻来爆一下,至于怎么加,我总结了一个最直观的示意图,如下:

Windows 10 IoT开发:HC-04超声波传感器测距(树莓派3)

简单来说,你需要2个电阻,一个4.3K欧,一个10K欧。为什么要这样呢,是因为根据 电压分配定律 ,如上图所示,4.3K和10K电阻的组合可以得到3.4V的输出。这对GPIO来说是可以接受的。如果你有别的值的电阻可以让输出正好3.3V也是可以的。我在淘宝买的常用电阻包没有办法配出正好3.3V,所以只能用4.3K和10K的组合。

然后,传感器和树莓派的连接也可以看上面这张图来连。VCC接树莓派的5V输出,TRIG接GPIO 23,ECHO通过一个4.3K电阻之后接GPIO 24,GND接Ground。

然后,爆代码就可以用一个现成的类,这是国外的 http://www.guruumeditation.net/en/digital-io-with-windows-10-iot-raspberry-pi-2-and-the-ultrasonic-ranging-module-hc-sr04/ 这篇文章里抄过来的。(稍微改进过)

using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Windows.Devices.Gpio;  namespace HC04 {     public class HC04UltrasonicDistanceSensor     {         private GpioPin Pin_Trig, Pin_Echo;         public double? Distance { get; }          /// <summary>         /// Available Gpio Pins. Refer: https://ms-iot.github.io/content/en-US/win10/samples/PinMappingsRPi2.htm         /// </summary>         public enum AvailableGpioPin : int         {             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 29             /// </summary>             GpioPin_5 = 5,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 31             /// </summary>             GpioPin_6 = 6,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 32             /// </summary>             GpioPin_12 = 12,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 33             /// </summary>             GpioPin_13 = 13,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 36             /// </summary>             GpioPin_16 = 16,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 12             /// </summary>             GpioPin_18 = 18,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 15             /// </summary>             GpioPin_22 = 22,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 16             /// </summary>             GpioPin_23 = 23,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 18             /// </summary>             GpioPin_24 = 24,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 22             /// </summary>             GpioPin_25 = 25,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 37             /// </summary>             GpioPin_26 = 26,             /// <summary>             /// Raspberry Pi 2 - Header Pin Number : 13             /// </summary>             GpioPin_27 = 27         }          public HC04UltrasonicDistanceSensor(AvailableGpioPin trigPin, AvailableGpioPin echoPin)         {             var gpio = GpioController.GetDefault();              Pin_Trig = gpio.OpenPin((int)trigPin);             Pin_Trig.SetDriveMode(GpioPinDriveMode.Output);             Pin_Trig.Write(GpioPinValue.Low);              Pin_Echo = gpio.OpenPin((int)echoPin);             Pin_Echo.SetDriveMode(GpioPinDriveMode.Input);         }          public double GetDistance()         {             var mre = new ManualResetEventSlim(false);              //Send a 10µs pulse to start the measurement             Pin_Trig.Write(GpioPinValue.High);             mre.Wait(TimeSpan.FromMilliseconds(0.01));             Pin_Trig.Write(GpioPinValue.Low);              var time = PulseIn(Pin_Echo, GpioPinValue.High, 500);              // multiply by speed of sound in milliseconds (34000) divided by 2 (cause pulse make rountrip)             var distance = time * 17000;             return distance;         }          private double PulseIn(GpioPin pin, GpioPinValue value, ushort timeout)         {             var sw = new Stopwatch();             var swTimeout = new Stopwatch();              swTimeout.Start();              // Wait for pulse             while (pin.Read() != value)             {                 if (swTimeout.ElapsedMilliseconds > timeout)                     return 3.5;             }             sw.Start();              // Wait for pulse end             while (pin.Read() == value)             {                 if (swTimeout.ElapsedMilliseconds > timeout)                     return 3.4;             }             sw.Stop();              return sw.Elapsed.TotalSeconds;         }     } }

使用方法如下:

public sealed partial class MainPage : Page {     public HC04UltrasonicDistanceSensor Hc04UltrasonicDistanceSensor { get; set; }     private DispatcherTimer _timer;      public MainPage()     {         this.InitializeComponent();         Hc04UltrasonicDistanceSensor = new HC04UltrasonicDistanceSensor(             HC04UltrasonicDistanceSensor.AvailableGpioPin.GpioPin_23,              HC04UltrasonicDistanceSensor.AvailableGpioPin.GpioPin_24);     }      protected override void OnNavigatedTo(NavigationEventArgs e)     {         base.OnNavigatedTo(e);          _timer = new DispatcherTimer();          _timer.Tick += (sender, o) =>         {             var distance = Hc04UltrasonicDistanceSensor.GetDistance();             var s = $"Distance : {distance} cm";             TxtDistance.Text = s;             Debug.WriteLine(s);         };          _timer.Interval = TimeSpan.FromSeconds(1);          _timer.Start();     } }

简单解释一下:

MainPage里的timer是用来定时每一秒取一次HC-04传感器返回的距离的,这个值可以自己改。这个距离是public double GetDistance()这个方法计算的。计算方法见代码注释。

原文  http://edi.wang/post/2016/4/2/windows-10-iot-hc04-ultra-sonic-distance
正文到此结束
Loading...