超声波传感器raspberry pi 2 c#.net

时间:2023-01-13 07:29:46

I'm trying to read the distance from an ultrasonic sensor (HC-SR04) but the only values I get is 0 and 265.xx.

我正在尝试读取超声波传感器(HC-SR04)的距离,但我得到的唯一值是0和265.xx.

I am using an Raspberry Pi 2 with Windows 10 IoT Core installed.

我正在使用安装了Windows 10 IoT Core的Raspberry Pi 2。

I've written the code in C#.

我用C#编写了代码。

This is the ultrasonic sensor class:

这是超声波传感器类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using Windows.Devices.Gpio;

namespace RaspberryPi
{
    class UcSensor
    {
        GpioController gpio = GpioController.GetDefault();

        GpioPin TriggerPin;
        GpioPin EchoPin;

        //Contructor
        public UcSensor(int TriggerPin, int EchoPin)
        {
            //Setting up gpio pin's
            this.TriggerPin = gpio.OpenPin(TriggerPin);
            this.EchoPin = gpio.OpenPin(EchoPin);

            this.TriggerPin.SetDriveMode(GpioPinDriveMode.Output);
            this.EchoPin.SetDriveMode(GpioPinDriveMode.Input);

            this.TriggerPin.Write(GpioPinValue.Low);
        }

        public double GetDistance()
        {
            ManualResetEvent mre = new ManualResetEvent(false);
            mre.WaitOne(500);

            //Send pulse
            this.TriggerPin.Write(GpioPinValue.High);
            mre.WaitOne(TimeSpan.FromMilliseconds(0.01));
            this.TriggerPin.Write(GpioPinValue.Low);

            //Recieve pusle
            while (this.EchoPin.Read() == GpioPinValue.Low)
            {
            }
            DateTime start = DateTime.Now;

            while (this.EchoPin.Read() == GpioPinValue.High)
            {
            }
            DateTime stop = DateTime.Now;

            //Calculating distance
            double timeBetween = (stop - start).TotalSeconds;
            double distance = timeBetween * 17000;

            return distance;
        }

    }
}

I've also written a script in python to read the values from the ultrasonic sensor and then it works but in c# I can't get it working.

我还在python中编写了一个脚本来读取超声波传感器的值,然后它可以正常工作但是在c#中我无法正常工作。

At the bottom you can find the debug log:

在底部,您可以找到调试日志:

'BACKGROUNDTASKHOST.EXE' (CoreCLR: DefaultDomain): Loaded 'C:\Program Files\WindowsApps\Microsoft.NET.CoreRuntime.1.0_1.0.22816.1_arm__8wekyb3d8bbwe\mscorlib.ni.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'BACKGROUNDTASKHOST.EXE' (CoreCLR: CoreCLR_UAP_Domain): Loaded 'C:\Users\DefaultAccount\AppData\Local\DevelopmentFiles\RaspiCarVS.Debug_ARM.chris\RaspiCar.winmd'. Symbols loaded. 'BACKGROUNDTASKHOST.EXE' (CoreCLR: CoreCLR_UAP_Domain): Loaded 'C:\Users\DefaultAccount\AppData\Local\DevelopmentFiles\RaspiCarVS.Debug_ARM.chris\System.Runtime.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'BACKGROUNDTASKHOST.EXE' (CoreCLR: CoreCLR_UAP_Domain): Loaded 'C:\Users\DefaultAccount\AppData\Local\DevelopmentFiles\RaspiCarVS.Debug_ARM.chris\WinMetadata\Windows.winmd'. Module was built without symbols. 'BACKGROUNDTASKHOST.EXE' (CoreCLR: CoreCLR_UAP_Domain): Loaded 'C:\Users\DefaultAccount\AppData\Local\DevelopmentFiles\RaspiCarVS.Debug_ARM.chris\System.Runtime.InteropServices.WindowsRuntime.dll'. Module was built without symbols. 'BACKGROUNDTASKHOST.EXE' (CoreCLR: CoreCLR_UAP_Domain): Loaded 'C:\Users\DefaultAccount\AppData\Local\DevelopmentFiles\RaspiCarVS.Debug_ARM.chris\System.Threading.dll'. Module was built without symbols. 'BACKGROUNDTASKHOST.EXE' (CoreCLR: CoreCLR_UAP_Domain): Loaded 'C:\Users\DefaultAccount\AppData\Local\DevelopmentFiles\RaspiCarVS.Debug_ARM.chris\System.Diagnostics.Debug.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'BACKGROUNDTASKHOST.EXE' (CoreCLR: CoreCLR_UAP_Domain): Loaded 'C:\Users\DefaultAccount\AppData\Local\DevelopmentFiles\RaspiCarVS.Debug_ARM.chris\System.Runtime.WindowsRuntime.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. Distance: 265.7457 Distance: 0 Distance: 0 Distance: 0 The program '[2508] BACKGROUNDTASKHOST.EXE' has exited with code 0 (0x0).

'BACKGROUNDTASKHOST.EXE'(CoreCLR:DefaultDomain):已加载'C:\ Program Files \ WindowsApps \ Microsoft.NET.CoreRuntime.1.0_1.0.22816.1_arm__8wekyb3d8bbwe \ mscorlib.ni.dll'。跳过加载符号。模块已经过优化,调试器选项“Just My Code”已启用。 'BACKGROUNDTASKHOST.EXE'(CoreCLR:CoreCLR_UAP_Domain):已加载'C:\ Users \ DefaultAccount \ AppData \ Local \ DevelopmentFiles \ RaspiCarVS.Debug_ARM.chris \ RaspiCar.winmd'。符号已加载。 'BACKGROUNDTASKHOST.EXE'(CoreCLR:CoreCLR_UAP_Domain):已加载'C:\ Users \ DefaultAccount \ AppData \ Local \ DevelopmentFiles \ RaspiCarVS.Debug_ARM.chris \ System.Runtime.dll'。跳过加载符号。模块已经过优化,调试器选项“Just My Code”已启用。 'BACKGROUNDTASKHOST.EXE'(CoreCLR:CoreCLR_UAP_Domain):已加载'C:\ Users \ DefaultAccount \ AppData \ Local \ DevelopmentFiles \ RaspiCarVS.Debug_ARM.chris \ WinMetadata \ Windows.winmd'。模块没有符号。 'BACKGROUNDTASKHOST.EXE'(CoreCLR:CoreCLR_UAP_Domain):已加载'C:\ Users \ DefaultAccount \ AppData \ Local \ DevelopmentFiles \ RaspiCarVS.Debug_ARM.chris \ System.Runtime.InteropServices.WindowsRuntime.dll'。模块没有符号。 'BACKGROUNDTASKHOST.EXE'(CoreCLR:CoreCLR_UAP_Domain):已加载'C:\ Users \ DefaultAccount \ AppData \ Local \ DevelopmentFiles \ RaspiCarVS.Debug_ARM.chris \ System.Threading.dll'。模块没有符号。 'BACKGROUNDTASKHOST.EXE'(CoreCLR:CoreCLR_UAP_Domain):已加载'C:\ Users \ DefaultAccount \ AppData \ Local \ DevelopmentFiles \ RaspiCarVS.Debug_ARM.chris \ System.Diagnostics.Debug.dll'。跳过加载符号。模块已经过优化,调试器选项“Just My Code”已启用。 'BACKGROUNDTASKHOST.EXE'(CoreCLR:CoreCLR_UAP_Domain):已加载'C:\ Users \ DefaultAccount \ AppData \ Local \ DevelopmentFiles \ RaspiCarVS.Debug_ARM.chris \ System.Runtime.WindowsRuntime.dll'。跳过加载符号。模块已经过优化,调试器选项“Just My Code”已启用。距离:265.7457距离:0距离:0距离:0节目'[2508] BACKGROUNDTASKHOST.EXE'已退出,代码为0(0x0)。

2 个解决方案

#1


Thanks for the reactions. DateTime was the problem i've now used the stopwatch class and now it works. Thanks a lot!

谢谢你的反应。 DateTime是我现在使用秒表类的问题,现在它可以工作了。非常感谢!

The working class:

工人阶级:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using Windows.Devices.Gpio;

namespace RaspberryPi
{
    class UcSensor
    {
        GpioController gpio = GpioController.GetDefault();

        GpioPin TriggerPin;
        GpioPin EchoPin;

        public UcSensor(int TriggerPin, int EchoPin)
        {
            this.TriggerPin = gpio.OpenPin(TriggerPin);
            this.EchoPin = gpio.OpenPin(EchoPin);

            this.TriggerPin.SetDriveMode(GpioPinDriveMode.Output);
            this.EchoPin.SetDriveMode(GpioPinDriveMode.Input);

            this.TriggerPin.Write(GpioPinValue.Low);
        }

        public double GetDistance()
        {
            ManualResetEvent mre = new ManualResetEvent(false);
            mre.WaitOne(500);
            Stopwatch pulseLength = new Stopwatch();

            //Send pulse
            this.TriggerPin.Write(GpioPinValue.High);
            mre.WaitOne(TimeSpan.FromMilliseconds(0.01));
            this.TriggerPin.Write(GpioPinValue.Low);

            //Recieve pusle
            while (this.EchoPin.Read() == GpioPinValue.Low)
            {
            }
            pulseLength.Start();


            while (this.EchoPin.Read() == GpioPinValue.High)
            {
            }
            pulseLength.Stop();

            //Calculating distance
            TimeSpan timeBetween = pulseLength.Elapsed;
            Debug.WriteLine(timeBetween.ToString());
            double distance = timeBetween.TotalSeconds * 17000;

            return distance;
        }

    }
}

#2


There is a better solution as the currently proposed answer will occasionally lock while getting the distance. The improved version of the code, which times out after 100 milliseconds (hardcoded). You can return a null or 0.0. Use double? if you want to return null.

有一个更好的解决方案,因为目前提出的答案有时会在获得距离时锁定。代码的改进版本,在100毫秒(硬编码)后超时。您可以返回null或0.0。用双?如果你想返回null。

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 MTP.IoT.Devices.Sensors
{
public class HCSR04
{
    private GpioPin triggerPin { get; set; }
    private GpioPin echoPin { get; set; }
    private Stopwatch timeWatcher;

    public HCSR04(int triggerPin, int echoPin)
    {
        GpioController controller = GpioController.GetDefault();
        timeWatcher = new Stopwatch();
        //initialize trigger pin.
        this.triggerPin = controller.OpenPin(triggerPin);
        this.triggerPin.SetDriveMode(GpioPinDriveMode.Output);
        this.triggerPin.Write(GpioPinValue.Low);
        //initialize echo pin.
        this.echoPin = controller.OpenPin(echoPin);
        this.echoPin.SetDriveMode(GpioPinDriveMode.Input);
    }

    public double GetDistance()
    {
        ManualResetEvent mre = new ManualResetEvent(false);
        mre.WaitOne(500);
        timeWatcher.Reset();
        //Send pulse
        this.triggerPin.Write(GpioPinValue.High);
        mre.WaitOne(TimeSpan.FromMilliseconds(0.01));
        this.triggerPin.Write(GpioPinValue.Low);
        return this.PulseIn(echoPin, GpioPinValue.High);           
    }

    private double PulseIn(GpioPin echoPin, GpioPinValue value)
    {
        var t = Task.Run(() =>
        {
            //Recieve pusle
            while (this.echoPin.Read() != value)
            {
            }
            timeWatcher.Start();

            while (this.echoPin.Read() == value)
            {
            }
            timeWatcher.Stop();
            //Calculating distance
            double distance = timeWatcher.Elapsed.TotalSeconds * 17000;
            return distance;
        });
        bool didComplete = t.Wait(TimeSpan.FromMilliseconds(100));
        if(didComplete)
        {
            return t.Result;
        }
        else
        {
            return 0.0;                
        }
    }

}
}

#1


Thanks for the reactions. DateTime was the problem i've now used the stopwatch class and now it works. Thanks a lot!

谢谢你的反应。 DateTime是我现在使用秒表类的问题,现在它可以工作了。非常感谢!

The working class:

工人阶级:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using Windows.Devices.Gpio;

namespace RaspberryPi
{
    class UcSensor
    {
        GpioController gpio = GpioController.GetDefault();

        GpioPin TriggerPin;
        GpioPin EchoPin;

        public UcSensor(int TriggerPin, int EchoPin)
        {
            this.TriggerPin = gpio.OpenPin(TriggerPin);
            this.EchoPin = gpio.OpenPin(EchoPin);

            this.TriggerPin.SetDriveMode(GpioPinDriveMode.Output);
            this.EchoPin.SetDriveMode(GpioPinDriveMode.Input);

            this.TriggerPin.Write(GpioPinValue.Low);
        }

        public double GetDistance()
        {
            ManualResetEvent mre = new ManualResetEvent(false);
            mre.WaitOne(500);
            Stopwatch pulseLength = new Stopwatch();

            //Send pulse
            this.TriggerPin.Write(GpioPinValue.High);
            mre.WaitOne(TimeSpan.FromMilliseconds(0.01));
            this.TriggerPin.Write(GpioPinValue.Low);

            //Recieve pusle
            while (this.EchoPin.Read() == GpioPinValue.Low)
            {
            }
            pulseLength.Start();


            while (this.EchoPin.Read() == GpioPinValue.High)
            {
            }
            pulseLength.Stop();

            //Calculating distance
            TimeSpan timeBetween = pulseLength.Elapsed;
            Debug.WriteLine(timeBetween.ToString());
            double distance = timeBetween.TotalSeconds * 17000;

            return distance;
        }

    }
}

#2


There is a better solution as the currently proposed answer will occasionally lock while getting the distance. The improved version of the code, which times out after 100 milliseconds (hardcoded). You can return a null or 0.0. Use double? if you want to return null.

有一个更好的解决方案,因为目前提出的答案有时会在获得距离时锁定。代码的改进版本,在100毫秒(硬编码)后超时。您可以返回null或0.0。用双?如果你想返回null。

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 MTP.IoT.Devices.Sensors
{
public class HCSR04
{
    private GpioPin triggerPin { get; set; }
    private GpioPin echoPin { get; set; }
    private Stopwatch timeWatcher;

    public HCSR04(int triggerPin, int echoPin)
    {
        GpioController controller = GpioController.GetDefault();
        timeWatcher = new Stopwatch();
        //initialize trigger pin.
        this.triggerPin = controller.OpenPin(triggerPin);
        this.triggerPin.SetDriveMode(GpioPinDriveMode.Output);
        this.triggerPin.Write(GpioPinValue.Low);
        //initialize echo pin.
        this.echoPin = controller.OpenPin(echoPin);
        this.echoPin.SetDriveMode(GpioPinDriveMode.Input);
    }

    public double GetDistance()
    {
        ManualResetEvent mre = new ManualResetEvent(false);
        mre.WaitOne(500);
        timeWatcher.Reset();
        //Send pulse
        this.triggerPin.Write(GpioPinValue.High);
        mre.WaitOne(TimeSpan.FromMilliseconds(0.01));
        this.triggerPin.Write(GpioPinValue.Low);
        return this.PulseIn(echoPin, GpioPinValue.High);           
    }

    private double PulseIn(GpioPin echoPin, GpioPinValue value)
    {
        var t = Task.Run(() =>
        {
            //Recieve pusle
            while (this.echoPin.Read() != value)
            {
            }
            timeWatcher.Start();

            while (this.echoPin.Read() == value)
            {
            }
            timeWatcher.Stop();
            //Calculating distance
            double distance = timeWatcher.Elapsed.TotalSeconds * 17000;
            return distance;
        });
        bool didComplete = t.Wait(TimeSpan.FromMilliseconds(100));
        if(didComplete)
        {
            return t.Result;
        }
        else
        {
            return 0.0;                
        }
    }

}
}