5

我正在关注将 C# 和 .net 微框架与 Parallax Ping 传感器连接的众多示例之一。

视差
http://learn.parallax.com/KickStart/28015

教程1
https://www.ghielectronics.com/community/codeshare/entry/123

教程 2
http://forums.netduino.com/index.php?/topic/1721-parallax-ping-ultrasonic-sensor/

我的传感器已正确连接到我的 netduino plus 的 5v 输出、接地和 gpio 0。(我尝试了不同的端口,但仍然得到相同的结果。

我遇到的问题是我的程序检测到高脉冲但从未检测到脉冲的低点。它卡在每个教程中的第二个 while(true) 循环中。此外,我的视差 LED 似乎一直亮着,根据文档,它应该随着每次 ping 突发脉冲,而不是无限期地亮着。我搞砸了使用 MS.SPOT.CPU.GPIO0 和 SecretLabs Pins.GPIOD0 枚举。秘密实验室引脚产生一个闪烁的 LED,永远不会退出第一个 while(true) 循环,而 MS.SPOT 端口产生一个永远不会退出第二个 while(true) 循环的 LED 灯。这是我在 MF 编程的第一天。谁能帮我指出可能是什么问题?

接线

它的视频在行动https://dl.dropboxusercontent.com/u/62170850/20140606_153029.mp4

看起来我已连接到引脚 10 和 13,但我没有。角度有误导。我实际上已插入 Gnd 和 11

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using Micro_Base_Lib;

namespace Parallax_Ping_Distance_Calculator
{
public class Program
{
    private static OutputPort onboardLed;
    private static InterruptPort onboardButton;
    public static void Main()
    {
        // write your code here
        //Cpu.GlitchFilterTime = new TimeSpan(0, 0, 0, 0, 5); //5 ms glitch filter

        onboardButton = new InterruptPort(Pins.ONBOARD_SW1, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLevelHigh);

        onboardButton.OnInterrupt += new NativeEventHandler(onboardButton_OnInterrupt);

        onboardLed = new OutputPort(Pins.ONBOARD_LED, false); //initial state off


        //go into powersave mode.
        Thread.Sleep(Timeout.Infinite);

    }

    static void onboardButton_OnInterrupt(uint data1, uint data2, DateTime time)
    {
        onboardLed.Write(true);
        onboardButton.ClearInterrupt();
        Ping myPinger = new Ping(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_D11);
        var dist = myPinger.GetDistance();

        var convertedDistance = myPinger.Convert(dist, DistanceUnits.cm);
        onboardLed.Write(false);
    }

}



    public enum DistanceUnits
    {
        mm,
        cm,
        dm,
        m,
        feet,
        inch,
        yard
    }

    public class Ping
    {
        TristatePort _port;
        DistanceUnits _unit = DistanceUnits.mm;

        double _soundSpeed = 343, _convertion = (10000 / 343) * 2; // default values

        public Ping(Cpu.Pin pin)
        {

            _port = new TristatePort(pin, false, false, ResistorModes.Disabled);
        }

        /// <summary>
        /// Automaticly adjust the convertion factor depending on air temperature.
        /// </summary>
        /// <param name="degC">The temperature in degrees celsius</param>
        public void AdjustSoundSpeed(double degC)
        {
            /* Speed of Sound (at 20 degrees celsius): 343 m/s
             * or
             * _soundSpeed = 331.4 + 0.6 * degC
             * 
             * There are 10,000,000 ticks per second.
             * 10,000,000 / _soundSpeed * 1000 can be simplyfied into:
             * 10,000 / _soundSpeed
             * times it by 2 because of round trip
             * then you get about 58.309 ticks per mm
             * 
             * then multiply if other unit is needed
             * 
             */
            _soundSpeed = 331.4 + 0.6 * degC;
            _convertion = (10000 / _soundSpeed) * 2;
        }

        private void WriteToLog(string s)
        {
            Debug.Print(DateTime.Now.ToString() + " : " + s);
        }
        /// <summary>
        /// Return the Ping))) sensor's reading in millimeters.
        /// </summary>
        /// <param name="usedefault">Set true to return value in the unit specified by the "Unit" property.
        /// Set false to return value in mm.</param>
        public double GetDistance()
        {
            bool lineState = false;
            long t1, t2;

            // Set it to an output

            if (!_port.Active) 
            _port.Active = true;
            WriteToLog("Port is in output mode");
            WriteToLog(_port.Id + " : " + "Mode: " + (_port.Active == true ? "Output" : "Input"));
            WriteToLog(_port.Id + " : " + "Read: " + _port.Read());

            //10 micro seconds is long enough for the parallax microphone to pick up a a ping.
            //http://www.parallax.com/sites/default/files/downloads/28015-PING-Detect-Distance.pdf - figure 3
            WriteToLog(_port.Id + " : " + "Mode: " + (_port.Active == true ? "Output" : "Input"));
            WriteToLog(_port.Id + " : " + "Read: " + _port.Read());
            _port.Write(true); //turns the port to high 3.3v
            WriteToLog("Signal pulse started");
            WriteToLog(_port.Id + " : " + "Mode: " + (_port.Active == true ? "Output" : "Input"));
            WriteToLog(_port.Id + " : " + "Read: " + _port.Read());
            _port.Write(false); //turns the port to low 0v
            WriteToLog("Signal pulse ended");
            WriteToLog(_port.Id + " : " + "Mode: " + (_port.Active == true ? "Output" : "Input"));
            WriteToLog(_port.Id + " : " + "Read: " + _port.Read());

            // Set port it as an input to pick up sound
            _port.Active = false;
            WriteToLog("Port is in input mode");
            WriteToLog(_port.Id + " : " + "Mode: " + (_port.Active == true ? "Output" : "Input"));
            WriteToLog(_port.Id + " : " + "Read: " + _port.Read());
            //wait for linestate to change to true. indicating the start of the pulse
            WriteToLog("Waiting for line state to turn to true.");
            while (lineState == false)
            {

                lineState = _port.Read();
                WriteToLog(_port.Id + " : " + "Mode: " + (_port.Active == true ? "Output" : "Input"));
                WriteToLog(_port.Id + " : " + "Read: " + _port.Read());
            }

            t1 = System.DateTime.Now.Ticks;
            WriteToLog("Line state reached high at : " + t1.ToString());

            WriteToLog("Waiting for line state to turn to false.");
            //wait for linestate to change to false. indicating the end of the pulse
            while (lineState == true)
            {

                lineState = _port.Read();
                WriteToLog(_port.Id + " : " + "Mode: " + (_port.Active == true ? "Output" : "Input"));
                WriteToLog(_port.Id + " : " + "Read: " + _port.Read());
            }
            t2 = System.DateTime.Now.Ticks;
            WriteToLog("Line state reached low at : " + t1.ToString());
            return Convert(((t2 - t1) / _convertion), _unit);
        }

        /// <summary>
        /// Convert the millimeters into other units.
        /// </summary>
        /// <param name="millimeters">The Ping))) sensor's mm reading.</param>
        /// <param name="outputUnit">The desired output unit.</param>
        public double Convert(double millimeters, DistanceUnits outputUnit)
        {
            double result = millimeters;

            switch (outputUnit)
            {
                case DistanceUnits.cm:
                    result = millimeters * 0.1F;
                    break;
                case DistanceUnits.dm:
                    result = millimeters * 0.01F;
                    break;
                case DistanceUnits.m:
                    result = millimeters * 0.001F;
                    break;
                case DistanceUnits.inch:
                    result = millimeters * 0.0393700787;
                    break;
                case DistanceUnits.feet:
                    result = millimeters * 0.0032808399;
                    break;
                case DistanceUnits.yard:
                    result = millimeters * 0.0010936133;
                    break;
            }

            return result;
        }

        public DistanceUnits Unit
        {
            get { return _unit; }
            set { _unit = value; }
        }
    }

}

06/01/2011 00:00:34:端口处于输出模式
06/01/2011 00:00:34:17:模式:输出
06/01/2011 00:00:34:17:读取:错误
06/ 01/2011 00:00:34 : 17 : 模式: 输出
06/01/2011 00:00:34 : 17 : 读取: False
06/01/2011 00:00:34 : 信号脉冲开始
06/01/2011 00 :00:34 : 17 : 模式: 输出
06/01/2011 00:00:34 : 17 : 读取: True
06/01/2011 00:00:34 : 信号脉冲结束
06/01/2011 00:00:34 : 17 : 模式: 输出
06/01/2011 00:00:34 : 17 : 读取: False
06/01/2011 00:00:34 : 端口处于输入模式
06/01/2011 00:00:34 : 17 : 模式: 输入
06/01/2011 00:00:34 : 17 : 读取: 假
06/01/2011 00:00:34 : 等待线路状态变为真。
06/01/2011 00:00:34:17:模式:输入
06/01/2011 00:00:34:17:读取:错误
06/01/2011 00:00:34:17:模式:输入
06/ 01/2011 00:00:34:17:读取:错误
06/01/2011 00:00:34:17:模式:输入
06/01/2011 00:00:34:17:读取:错误
06/01/ 2011 00:00:34 : 17 : 模式: 输入
06/01/2011 00:00:34 : 17 : 读取: 假
06/01/2011 00:00:34 : 17 : 模式: 输入
06/01/2011 00 :00:34 : 17 : 读取: 错误
06/01/2011 00:00:34 : 17 : 模式: 输入
06/01/2011 00:00:34 : 17 : 读取: 错误
06/01/2011 00:00 :34 : 17 : 模式: 输入
06/01/2011 00:00:34 : 17 : 读取: 假
06/01/2011 00:00:34 : 17 : 模式: 输入
06/01/2011 00:00:34 : 17 : 读: 假
06/01/2011 00:00:34:17:模式:输入
06/01/2011 00:00:34:17:读取:错误
06/01/2011 00:00:34:17:模式:输入
06/ 01/2011 00:00:34:17:读取:错误
06/01/2011 00:00:34:17:模式:输入
06/01/2011 00:00:34:17:读取:错误
06/01/ 2011 00:00:34 : 17 : 模式: 输入
06/01/2011 00:00:34 : 17 : 读取: 假
06/01/2011 00:00:34 : 17 : 模式: 输入
06/01/2011 00 :00:34 : 17 : 读取: 错误
06/01/2011 00:00:34 : 17 : 模式: 输入
06/01/2011 00:00:34 : 17 : 读取: 错误
06/01/2011 00:00 :34 : 17 : 模式: 输入
06/01/2011 00:00:34 : 17 : 读取: 假
06/01/2011 00:00:34 : 17 : 模式: 输入
06/01/2011 00:00:34 : 17 : 读: 假
06/01/2011 00:00:34:17:模式:输入
06/01/2011 00:00:34:17:读取:错误
06/01/2011 00:00:34:17:模式:输入
06/ 01/2011 00:00:34 : 17 :读取:错误
06/01/2011 00:00:35 : 17 :模式:输入

4

4 回答 4

1

The trick is that it is not really an echo signal, it is a timing signal that represents the echo returned. Actually an average of 8 separate echos I think.

    pingTrig = new OutputPort(trig, false);
    pingEcho = new InterruptPort(echo, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);  // it is not really an echo
    pingEcho.OnInterrupt += (p, s, t) =>
    {
        if (s == 0)
            pingFall = t.Ticks;
        else
            pingRise = t.Ticks;
    };

Then

    pingEcho.EnableInterrupt();
    pingTrig.Write(true);
    Thread.Sleep(1);
    pingTrig.Write(false);
    Thread.Sleep(35);      // I hate waiting
    pingEcho.DisableInterrupt();

and

    int Distance { get { return (int)((pingFall > pingRise) ? (pingFall - pingRise) : maxPingDistance); } }

somewhere.

On the netduino the hardware gets the interrupts, but queues an event you receive later. Fortunately it is Timestamped.

It also is very bad idea to do that much from another interrupt routine. Set a flag indicating the button press should be processed, and get out of the interrupt. Then in you regular main loop, do the ping work (pulse trigger, wait for echo). Technically, you aren't really in the interrupt routine, but I just think it makes more sense from a 'good practices' point of view to treat it as though you are.

于 2014-09-11T19:58:21.323 回答
1

我在我的 NetDuino Plus 上实现了您的代码,经过一番修改(我没有与您完全相同的传感器,因此我不得不稍微修改您的代码),一切似乎都运行良好。所以在回溯代码后我注意到你正在使用

Cpu.Pin.GPIO_Pin0

就像我按照旧习惯写的那样

Pins.GPIO_PIN_D0

您会看到 Cpu.Pin 指的是实际的 mCPU 引脚,如 Pins.GPIO_PIN_D* 指的是 NetDuino 开发板上的引脚输出。

所以改变

Cpu.Pin.GPIO_Pin0

Pins.GPIO_PIN_D0

这应该可以解决您问题中所述的问题。

于 2014-06-05T21:56:22.793 回答
1

可能有点晚了,但我在 SIG 上看不到 1K 电阻,它出现在第一个链接上。由于安培数,这可能会导致问题。

于 2015-03-17T23:15:24.567 回答
0

我绝对建议在 Ping 传感器上使用上拉电阻,这些超声波传感器几乎都是同一种设备——1970 年代的宝丽来 SX-70 陆地相机用它来确定距离。

于 2015-05-31T18:28:08.040 回答