Windows 10 IoT Coreのタイマー関係を調べてみる(追記)

Windows 10 IoT Coreのタイマー関係を調べてみる(追記)

前回のエントリーの続編となります。

uepon.hatenadiary.com

前回のエントリーでmsecレベルのdelayは難しいのかなと思っていたのですが、Facebook上でMatsuokaさんからコメントで

「sw.ElapsedMilliseconds がNG」

というコメントをいただき

ソースもいただけました。ありがとうございます。

以下のようにすればμsec単位のdelayができるということでやってみました。

private static void xDelay(int microSeconds)
{
    var ticks = (long)(microSeconds * Stopwatch.Frequency / 1e6);

    var sw = new Stopwatch();
    sw.Restart();
    while (sw.ElapsedTicks <= ticks)
    {
        // Nothing.
    }
}

Ticksを使うっていうのはあながち間違っていなかったようなのですが、System.Diagnostics.Stopwatch.FrequencyでTicksの周波数をμ秒の単位に合わせて Ticksの値が該当の値になるようにすることでうまくできるようです。

https://msdn.microsoft.com/ja-jp/library/system.diagnostics.stopwatch.frequency(v=vs.110).aspx

上の例ではμ秒なので1e6=1000000で割ることで1マイクロ秒あたりのTicksを計算しています。

このxDelay()メソッドを使って以下のようにコードを書いて実験をすると

private string delay(int msec)
{
    var times = 0;

    s.Restart();
    for (times = 0; times < 1000; times++)
    {
        if (pin.Read() == GpioPinValue.High)
        {
            pin.Write(GpioPinValue.Low);
        }
        else
        {
            pin.Write(GpioPinValue.High);
        }
        xDelay(msec*1000); //引数はμsec単位なので1000倍してmsec単位にしています
    }
    s.Stop();

    return msec.ToString() + "msec->" + s.ElapsedMilliseconds / (double)times + "ms" + Environment.NewLine;
}

f:id:ueponx:20160819233559j:plain

このようになります。GPIOの処理も行っているので少し負荷がかかっていると思いますが以前に比べると大きく処理が改善しています。 RaspberryPi2で実行していますが、RaspberryPi3でも同じような結果になるそうです。

以下がダメダメだった時の結果。

f:id:ueponx:20160813170143j:plain

誤差の1msec以下なのでかなりいい感じになっています。これならかなりいい感じで使用できそうです。 Matsuokaさん、アドバイスありがとうございました。