【问题标题】:Greater time resolution using .NET Micro Framework on Netduino board (for dimming an LED)?在 Netduino 板上使用 .NET Micro Framework 获得更高的时间分辨率(用于调光 LED)?
【发布时间】:2011-05-18 06:15:25
【问题描述】:

我正在使用 .NET Micro Framework 4.1 对Netduino 板进行编程,并希望获得比毫秒更高的时间分辨率。这是因为我试图通过快速闪烁来调暗 LED。

问题在于示例代码使用了Thread.Sleep(..),这需要几毫秒。

来自http://netduino.com/projects/ 的示例代码显示了相关问题:

OutputPort ledOnboard = new OutputPort(Pins.ONBOARD_LED, false);
while (true)
{
    ledOnboard.Write(true);
    Thread.Sleep(1); // << PROBLEM: Can only get as low as 1 millisecond

即使有另一种方法可以通过不使用更大的时间分辨率来完成调光,我也很乐意。

【问题讨论】:

标签: c# .net-micro-framework netduino


【解决方案1】:

这并不能回答您关于获得更好时间分辨率的问题,但它确实解决了您更改LED 亮度的问题。您应该为 Netduino 使用 PWM 模块。

Netduino Basics: Using Pulse Width Modulation (PWM) 是一篇关于如何使用它的好文章。

【讨论】:

  • 我可能会在下一次电子课程期间研究 pwm 模块,然后更新此线程。谢谢。
  • Netduino 2 现在允许您使用带有板载 LED 的 PWM 通道。
【解决方案2】:

我过去也遇到过类似的问题,使用下面的方法来计时在微秒范围内。第一行确定一毫秒内有多少滴答声(我使用它已经有一段时间了,但我认为 1 个滴答声是 10 微秒)。第二行获取系统已开启的时间量(以滴答计)。我希望这会有所帮助。

public const Int64 ticks_per_millisecond = System.TimeSpan.TicksPerMillisecond;

public static long GetCurrentTimeInTicks()
{
    return Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks;
}

【讨论】:

  • NETMF 似乎不支持接受 TimeSpan 对象的 Timer 构造函数,这将允许 John 以刻度为单位设置周期。
  • 这很好用,只是写了一个快速等待函数。戴夫,你在抽什么? NETMF 不仅在 Timer 的构造函数中支持 TimeSpan(看看重载,兄弟),而且这与此解决方案完全无关。只需坐在繁忙的循环中,等待所需的滴答数过去。查看我在编辑中添加的功能。
  • 很容易知道,但我个人仍然会使用 PWM 来处理 LED。
【解决方案3】:

您可以使用计时器来引发事件,而不是使用睡眠。

计时器上的 Interval 属性是双精度的,因此您可以在其上设置不到一毫秒的时间。

http://msdn.microsoft.com/en-us/library/0tcs6ww8(v=VS.90).aspx

【讨论】:

  • 我在测试之前对此表示赞同...哎呀。间隔实际上是 int 或 TimeSpan,看起来它也具有 ms 分辨率。因此,我认为这不是 John 的有效解决方案。
  • 我收回了这一点——虽然我仍然需要对其进行测试,但其他答案之一表明您可以获得每毫秒的滴答数,在我的板上我得到了 10,000。所以我们每个人 10 个滴答声并不算太破旧(如果它真的有效的话):)
  • 这实际上行不通。虽然 System.TimeSpan 确实具有亚毫秒级的分辨率,但它实际上不会以请求的分辨率触发您的事件。您最好的活动是在一段时间循环中查看 Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks。如下所示,TimeSpan 有一个静态属性,它会告诉你一秒、毫秒、分钟、小时等有多少滴答声……
【解决方案4】:

在他对Seidleroni's answerBrainSlugs83 的评论中建议“坐在忙碌的循环中,等待所需的滴答数过去。请参阅我在编辑中添加的功能”。但我看不到添加到编辑中的功能。我认为它会是这样的:

using System;
using Microsoft.SPOT.Hardware;

private static long _TicksPerMicroSecond = TimeSpan.TicksPerMillisecond/1000;

private void Wait(long microseconds)
{
    var then = Utility.GetMachineTime().Ticks;
    var ticksToWait = microseconds * _TicksPerNanoSecond;
    while (true)
    {
        var now = Utility.GetMachineTime().Ticks;
        if ((now - then) > ticksToWait) break;
    }
}

【讨论】:

    【解决方案5】:

    您可能没有想到的一点是,您的代码依赖于 .NET System 命名空间,该命名空间基于您 PC 中的实时时钟。请注意,答案取决于设备中的计时器。

    接下来,我建议您花一点时间来确定您在代码中使用的信息的来源——它是 .NET 是否正确(基本上基于您的 PC),还是代码所在的设备运行在(例如,哪个将具有 System 以外的命名空间)?

    PWM 是人为控制直流电流的好方法(通过改变脉冲宽度),但在一天结束时改变 PWM 频率仍然是时间的函数。

    而不是使用延迟......像睡眠......你可能想要产生一个线程并让它管理亮度。使用 Sleep 基本上仍然是一种直线程序方法,如果您使用单线程,您的代码将只能做这件事。

    【讨论】:

      猜你喜欢
      • 2016-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 1970-01-01
      相关资源
      最近更新 更多