最近在做双sensor同步的测试,然后sensor获取图像送给算法,算法识别成数字时间,通过比较时间从而判断时间的延时。
算法识别就是需要背景比较单一,字体可以随意放大。在网上找了好几个ms级别的定时器,都不是很满足要求。所以用c#写了一个定时器。
首先网上找了一个基于c#的 精确定时器的类,
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Threading;
namespace WindowsFormsApplication1
{
///
/// ManualTimer
/// A simulated timer by loop
/// It creates a new thread in Thread Pool using ThreadPool class
/// Nocky Tian @ 2008-3-16
///
/// The timer starts a new thread using object,
/// and the value of the property Priority is set to
/// so that the accuray could be kept 1ms around.
///
///
///
///
public class UltraHighAccurateTimer
{
public delegate void ManualTimerEventHandler(object sender);
public event ManualTimerEventHandler Tick;
private long clockFrequency; // result of QueryPerformanceFrequency()
private bool running = false;
private Thread timerThread;
private int intervalMs; // interval in mimliseccond;
///
/// Timer inteval in milisecond
///
public int Interval
{
get { return intervalMs; }
set
{
intervalMs = value;
intevalTicks = (long)((double)value * (double)clockFrequency / (double)1000);
}
}
private long intevalTicks;
///
/// Pointer to a variable that receives the current performance-counter value, in counts.
///
///
/// If the function succeeds, the return value is nonzero.
///
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
///
/// Pointer to a variable that receives the current performance-counter frequency,
/// in counts per second.
/// If the installed hardware does not support a high-resolution performance counter,
/// this parameter can be zero.
///
///
/// If the installed hardware supports a high-resolution performance counter,
/// the return value is nonzero.
///
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);
public UltraHighAccurateTimer()
{
if (QueryPerformanceFrequency(out clockFrequency) == false)
{
// Frequency not supported
throw new Win32Exception("QueryPerformanceFrequency() function is not supported");
}
}
///
/// 进程主程序
///
///
private void ThreadProc()
{
long currTime;
long nextTriggerTime; // the time when next task will be executed
GetTick(out currTime);
nextTriggerTime = currTime + intevalTicks;
while (running)
{
while (currTime < nextTriggerTime)
{
GetTick(out currTime);
} // wailt an interval
nextTriggerTime = currTime + intevalTicks;
if (Tick != null)
{
Tick(this);
}
}
}
public bool GetTick(out long currentTickCount)
{
if (QueryPerformanceCounter(out currentTickCount) == false)
throw new Win32Exception("QueryPerformanceCounter() failed!");
else
return true;
}
public void Start()
{
running = true;
timerThread = new Thread(new ThreadStart(ThreadProc));
timerThread.Name = "HighAccuracyTimer";
timerThread.Priority = ThreadPriority.Highest;
timerThread.Start();
}
public void Stop()
{
running = false;
timerThread.Abort();
}
~UltraHighAccurateTimer()
{
running = false;
timerThread.Abort();
}
}
}
然后就是自己加label,显示出来
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
UltraHighAccurateTimer mytimer = new UltraHighAccurateTimer();
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
System.Windows.Forms.Form.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
Point pt = new Point();
pt.X = (this.Width - this.label1.Width) / 2;
pt.Y = (this.Height - this.label1.Height) / 2 + 100;
this.label1.Location = pt;
mytimer.Interval = 1; //定时间隔100毫秒
mytimer.Tick += new UltraHighAccurateTimer.ManualTimerEventHandler(uhat_Tick);
mytimer.Start();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
mytimer.Stop();
}
void uhat_Tick(object sender)
{
string str = DateTime.Now.ToString("ss.fff");
this.label1.Text = str;
}
protected override void OnNotifyMessage(Message m)
{
//Filter out the WM_ERASEBKGND message
if (m.Msg != 0x14)
{
base.OnNotifyMessage(m);
}
}
private void Form1_SizeChanged(object sender, EventArgs e)
{
Point pt = new Point();
pt.X = (this.Width - this.label1.Width) / 2;
pt.Y = (this.Height - this.label1.Height) / 2 + this.label1.Height/2;
this.label1.Location = pt;
}
}
}
设计代码
namespace WindowsFormsApplication1
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("黑体", 120F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label1.Location = new System.Drawing.Point(122, 190);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(554, 161);
this.label1.TabIndex = 1;
this.label1.Text = "label1";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(784, 561);
this.Controls.Add(this.label1);
this.Name = "Form1";
this.Text = "Form1";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.Load += new System.EventHandler(this.Form1_Load);
this.SizeChanged += new System.EventHandler(this.Form1_SizeChanged);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
}
}
设计界面
最后运行结果如下