タイマの精度測定
System.Windows.Forms.Timerとマルチメディアタイマの精度を比較してみました。
測り方は各タイマのイベント発生を100ms毎に設定しシリアルポートにデータ送信させ、オシロスコープでシリアルポートの送信間隔を確認します。
タイマイベント発生間隔(データ送信間隔)のばらつきを確認するためオシロスコープは取得した波形を重ね書きするモードにしておきます。
System.Windows.Forms.Timerの精度
コード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private System.Windows.Forms.Timer timer1;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
serialPort1.BaudRate = 9600;
serialPort1.Parity = Parity.None;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
serialPort1.Handshake = Handshake.None;
serialPort1.PortName = "COM3";
serialPort1.Open();
timer1 = new System.Windows.Forms.Timer();
timer1.Tick += new System.EventHandler(timer1_Tick);
timer1.Interval = 100;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
byte[] sendData = { 0xff };
serialPort1.Write(sendData,0,sendData.Length);
}
}
}
結果
設定値の100msに対して-4ms~+24msでした。頻度的にも+側のずれの方が多そうでした。
マルチメディアタイマの精度
コード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
[DllImport("winmm.dll", SetLastError = true)]
static extern UInt32 timeSetEvent(UInt32 uDelay, UInt32 uResolution, LPTIMECALLBACK lpTimeProc, UInt32 dwUser, UInt32 fuEvent);
[DllImport("winmm.dll", SetLastError = true)]
static extern UInt32 timeKillEvent(UInt32 uTimerID);
private delegate void LPTIMECALLBACK(UInt32 uTimerID, UInt32 uMsg, UInt32 dwUser, UInt32 dw1, UInt32 dw2);
private UInt32 timer_id;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
serialPort1.BaudRate = 9600;
serialPort1.Parity = Parity.None;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
serialPort1.Handshake = Handshake.None;
serialPort1.PortName = "COM3";
serialPort1.Open();
timer_id = timeSetEvent(100, 1, Timer_Callback, 0, 1);
//周期100ms,分解能1ms,繰り返しイベント発生
}
~Form1()
{
timeKillEvent(timer_id);
}
private void Timer_Callback(UInt32 uTimerID, UInt32 uMsg, UInt32 dwUser, UInt32 dw1, UInt32 dw2)
{
byte[] sendData = { 0xff };
serialPort1.Write(sendData, 0, sendData.Length);
}
}
}
結果
設定値の100msに対して-1ms~+1msでした。
コメント