時刻・時間・タイマ

   

■ 現在の年月日時分秒の取得

      現在の年月日時分秒 及び曜日の取得の例を示します
実行結果
 
   <プログラム例>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace nowTime
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
        
            label1.Text = string.Format("ToLongDateString =   {0}", dt.ToLongDateString());//2012年3月31日
            label2.Text = string.Format("ToLongTimeString =   {0}",dt.ToLongTimeString());//18:53:13
            label3.Text = string.Format("ToShortDateString =   {0}",dt.ToShortDateString());//12/03/31(土)
            label4.Text = string.Format("ToShortTimeString =   {0}",dt.ToShortTimeString());//18:54
            label5.Text = string.Format("ToString =   {0}",dt.ToString());//12/03/31(土)18:54:23
            label6.Text = string.Format("Year.ToString =   {0}", dt.Year.ToString());//2012
            label7.Text = string.Format("Month.ToString =   {0}", dt.Month.ToString());//3
            label8.Text = string.Format("Day.ToString =   {0}", dt.Day.ToString());//31
            label9.Text = string.Format("DayofWeek.ToString =  {0}", dt.DayOfWeek.ToString());//Saturday
            label13.Text = ("日月火水木金土").Substring(int.Parse(dt.DayOfWeek.ToString("d")), 1);//土
            label10.Text = string.Format("Hour.ToString =   {0}", dt.Hour.ToString());//18
            label11.Text = string.Format("Minute.ToString =   {0}", dt.Minute.ToString());//56
            label12.Text = string.Format("Second.ToString =   {0}", dt.Second.ToString());//23

            label14.Text = string.Format("ToString(\"yyyy/MM/dd  HH:mm:ss\") =   {0}", dt.ToString("yyyy/MM/dd  HH:mm:ss"));//12/03/31 18:54:23





        }
    }
}









■ Windows 起動後の経過時間の取得

     GetTickCount ( )の戻り値として、 Windowsが起動してからの時間をmsec単位で取得できます。但し、戻り値は
32ビットですので 49.7 日間連続して動作させると、経過時間は 0 に戻ります。
実行結果
   <プログラム例>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;   //API関数を使用する場合必要

namespace windowsTime
{
    public partial class Form1 : Form
    {
        [DllImport("Kernel32.dll")]  public static extern UInt32 GetTickCount();  



        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            uint winTime;

            winTime = GetTickCount();
           
            
            uint myHour = (uint)(winTime /1000 / 60/ 60);
            uint temp = winTime % (1000 * 60 * 60);

            uint myMin = (uint)(temp /1000 / 60);
            temp = (uint)(temp % (1000 * 60));

            uint mySec = (uint)(temp /1000 );
            temp = (uint)(temp % 1000);

            uint mymSec = temp;
            
            label1.Text = string.Format("{0:#,0}[msec]",winTime);   //3桁区切り
                                                                    //  H    min    sec    msec
            label2.Text = string.Format("= {0}H {1}min {2}sec {3}msec", myHour, myMin, mySec, mymSec);
            
        }
    }
}








■ ワンショット タイマ

   数十mesc程度の誤差を問題としないなら Timerコンポーネントを使ってWindowsタイマ(System.Windows.Forms.Timerクラス)を使うことにより簡単にタイマアプリケーションが作成できます。
 以下はタイマコンポーネントを3個使ったワンショットタイマです。 タイマが同時に動作しないならタイマコンポーネントは1個でOKです。
   
  <プログラム例>

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 _200z_delay
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

}

private void delay_ms_1(int delayTime) //遅延関数  //遅延時間 delayTime[msec]
{
timer1.Interval = delayTime;
timer1.Enabled = true;

label1.Text = "timer1: running";
label1.ForeColor = Color.Red; //文字色→赤
label1.BackColor = Color.Yellow;//背景色→黄
}


private void delay_ms_2(int delayTime) //遅延関数  //遅延時間 delayTime[msec]
{
timer2.Interval = delayTime;
timer2.Enabled = true;

label2.Text = "timer2: running";
label2.ForeColor = Color.Red; //文字色→赤
label2.BackColor = Color.Yellow;//背景色→黄

}


private void delay_ms_3(int delayTime) //遅延関数  //遅延時間 delayTime[msec]
{
timer3.Interval = delayTime;
timer3.Enabled = true;

label3.Text = "timer3: running";
label3.ForeColor = Color.Red; //文字色→赤
label3.BackColor = Color.Yellow;//背景色→黄
}


private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;

label1.Text = "timer1: stopped";
label1.ForeColor = Color.Black; //文字色→赤
label1.BackColor = Color.LightGray;//背景色→黄

}



private void timer2_Tick(object sender, EventArgs e)
{
timer2.Enabled = false;

label2.Text = "timer2: stopped";
label2.ForeColor = Color.Black; //文字色→赤
label2.BackColor = Color.LightGray;//背景色→黄
}



private void timer3_Tick(object sender, EventArgs e)
{
timer3.Enabled = false;

label3.Text = "timer3: stopped";
label3.ForeColor = Color.Black; //文字色→赤
label3.BackColor = Color.LightGray;//背景色→黄
}

private void button1_Click(object sender, EventArgs e)
{
delay_ms_1(1000);
}

private void button2_Click(object sender, EventArgs e)
{
delay_ms_2(2000);

}

private void button3_Click(object sender, EventArgs e)
{
delay_ms_3(5000);
}
}
}

   
 
タイマ 停止中
   
 
タイマ動作中: ラベルの色が黄色になっています。
   





 ストップウォッチ(マルチメディアタイマ)

    精度の高い時間制御をおこなう方法としてマルチメディアタイマを使う方法があります。
以下に、マルチメディアタイマを使用したストップウォッチの例を示します
実行結果
  
   <プログラム例>
//Form1.Desiner.cs
// internal System.Windows.Forms.Button button1;    //private → internal 必須
// private System.Windows.Forms.Label label1;
// internal System.Windows.Forms.PictureBox pictureBox1;   //private → internal 必須
// private System.Windows.Forms.Button button2;



//Form.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;   //API関数を使用する場合必要

namespace mmTimer_oneFile
{
    public partial class Form1 : Form
    {
        public bool start_stop;              //スタートストップ フラグ
        public mmTimer mmtimer = new mmTimer();     // クラスmmTimerのインスタンス生成
        public long total_time = 0;                 //累積時間[msec]
       

        public Form1()
        {
            InitializeComponent();
            mmtimer.loadForm(this);
            mmtimer.mmTimerID = (IntPtr)0;   //mmタイマのIDを0に宣言

            start_stop = false; 
            button1.Text = "Start";

        }

        private void button1_Click(object sender, EventArgs e)
        {

            if (start_stop == false)    //mmタイマが停止中の場合
            {
                start_stop = true;
                button1.Text = "Stop";
                mmtimer.timerStart();                //mmタイマをスタートさせる
            }
            else
            {
                start_stop = false;
                button1.Text = "Start";
                mmtimer.timerStop();              //mmタイマを停止させる
            }

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (start_stop == true)
            {
                mmtimer.timerStop();        //タイマ停止
                Application.DoEvents();     //メッセージ キューにある Windows メッセージをすべて処理

            }
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            Font objFont = new Font("MS ゴシック", 40);

            String str = string.Format("{0:#,0}", total_time);
            g.DrawString(str, objFont, Brushes.Red, 0, 0);


        }

        private void button2_Click(object sender, EventArgs e)
        {
            total_time = 0;
            pictureBox1.Refresh();
        }
    }

    public class mmTimer    //マルチメディアタイマ クラス
    {
        Form1 form1;  // Form1のオブジェクト生成

        public IntPtr mmTimerID = (IntPtr)0;// マルチメディアタイマーのIDの宣言

        // timeSetEventで指定するタイマーコールバック関数をデリゲートで定義
        private delegate void TimerProcDelegate(IntPtr uID, int uMsg, mmTimer Inst, int dw1, int dw2);
        private TimerProcDelegate Proc = TimerProc;  // TimerProcDelegate型にTimerProc関数を代入
        private delegate void RefreshDelegate(); // マルチメディアタイマーのコールバック関数内で使用する関数をデリゲートで定義



        [DllImport("winmm.dll")]
        private extern static IntPtr timeSetEvent(int uDelay, int uResolution, TimerProcDelegate lpFunction, mmTimer mmT, int uFlags);
        //MMRESULT timeSetEvent(         //VS SetTimer
        //UINT uDelay,   //イベント遅延をミリ秒で指定します
        //UINT uResolution,     //タイマイベントの分解能をミリ秒で指定します。
        //LPTIMECALLBACK lpTimeProc,    //コールバック関数のアドレスを指定します。
        //DWORD dwUser,         //ユーザーが提供するコールバックデータを指定します
        //UINT fuEvent      //下記タイマイベントのタイプを指定します
        //                  //TIME_ONESHOT      イベントは、uDelay ミリ秒経過後に 1 度発生します。
        //                  //TIME_PERIODIC     イベントは、uDelay ミリ秒ごとに発生します
        //);

        [DllImport("winmm.dll")]
        private extern static int timeKillEvent(IntPtr uID);        //指定されたタイマイベントを停止します。
        //MMRESULT timeKillEvent(
        //  UINT uTimerID       //停止するタイマのID
        //);

        [DllImport("winmm.dll")]
        private extern static int timeBeginPeriod(int uPeriod); //アプリケーションまたはデバイスドライバの最小タイマ分解能を、ミリ秒単位で指定します

        [DllImport("winmm.dll")]
        private extern static int timeEndPeriod(int uPeriod);   //以前にセットされた最小タイマ分解能をクリアします。


        public void timerStart()   // タイマースタート
        {
            if (mmTimerID == (IntPtr)0) //lTimerEventID が 0(何も設定されていない)場合 → mmTimerが停止している場合
            {
                timeBeginPeriod(1);    //最少タイマ分解能を1msecに設定
         
                mmTimerID = timeSetEvent(1, 0, Proc, this, 1); //インターバル時間:1msec、分解能:0(システムの最少)、コールバック関数のアドレス:Proc、1:TIME_PERIDIC  
//              mmTimerID = timeSetEvent(10, 0, Proc, this, 1); //インターバル時間:10msec、分解能:0(システムの最少)、コールバック関数のアドレス:Proc、1:TIME_PERIDIC  

            }
        }

        public static void TimerProc(       // マルチメディアタイマーコールバック関数
        IntPtr uTimerID,    //タイマID
        int uMsg,           //メッセージを識別する整数
        mmTimer mmT,      //timeSetEvent( , , , SWModule Inst(第4引数), XX )の第4引数から渡されるユーザデータ    // DWORD dwUser, // ユーザー定義
        int dw1,    //予約
        int dw2     //予約
        )
        {
            if (mmT.mmTimerID == uTimerID)
            {
               
                mmT.form1.total_time++; // 1msec経過したとして +1をトータルタイムに加算
//                mmT.form1.total_time += 10; // 10msec経過したとして +10をトータルタイムに加算

                mmT.form1.Invoke(new RefreshDelegate(mmT.form1.pictureBox1.Refresh));     //pictureBox1 リフレッシュ
            }
        }



        public void timerStop()
        {

            if (mmTimerID != (IntPtr)0) //mmTimerが 0でない場合 → 動作中の場合
            {
                timeKillEvent(mmTimerID);   //  タイマ停止                                           
                timeEndPeriod(1); //以前にセットされた最小タイマ分解能をクリア
                mmTimerID = (IntPtr)0;
            }


        }

        public void loadForm(Form Form1) // フォームオブジェクト格納
        {
            form1 = (Form1)Form1;   //
        }
    }


}


■ 正弦波形描画(1msec毎、マルチメディアタイマ

    1msec_毎にマルチメディアタイマをもちいて正弦波形を描いた例です。(→ プロジェクトファイル) 動作結果
   
   <プログラム例>

//----------------------------------------
//Form1.Desiner.cs

//   private System.Windows.Forms.Button button1;
//   private System.Windows.Forms.Button button2;
//   internal System.Windows.Forms.PictureBox pictureBox1;
//   private System.Windows.Forms.Label label1;
//-------------------------------------- //Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace mmT_Sin { public partial class Form1 : Form { private bool start_stop; //スタートストップ フラグ public long total_time = 0; //累計msec public int Count1000 = 0; //1sec private mmTimer mmtimer = new mmTimer(); // クラスmmTimerのインスタンス生成 private int x0 = 100, y0 = 500; //原点座標 private int xMAX = 1000, yMAX = 400; private int ColorFlag = 0; //0:赤  1:青 //デリゲートの宣言する delegate void MyDelegate(); public Form1() { InitializeComponent(); mmtimer.loadForm(this); mmtimer.mmTimerID = (IntPtr)0; //mmタイマのIDを0に宣言 start_stop = false; button1.Text = "Start"; button2.Text = "Reset"; this.WindowState = FormWindowState.Maximized; //Windowフォームを最大化 } public void Invoke_request() //祈願によりデリゲートを呼出す、 { Invoke(new MyDelegate(mmTUpdate)); } public void mmTUpdate() //1msec毎のコールバック { int tempX,tempY; Graphics g = this.CreateGraphics(); //Form1へのGraphicsオブジェクトを作成 Bitmap bmp = new Bitmap(1, 1); //サイズが1ドット×1ドットのBitmapオブジェクトを作成 Count1000++; tempX = Count1000; if(Count1000 >= 1000) { Count1000 = 0; if (ColorFlag == 1) ColorFlag = 0; else ColorFlag = 1; } if (ColorFlag == 0) { bmp.SetPixel(0, 0, Color.Blue); //座標(0,0)を赤色に設定 } else { bmp.SetPixel(0, 0, Color.Red); //座標(0,0)を赤色に設定 } tempX = Count1000; tempY = (int)(yMAX * Math.Sin(2 * Math.PI * tempX / 1000)); g.DrawImageUnscaled(bmp, x0 + tempX, y0 + tempY); //Form1の座標(10,10)を基準点としてBitmapオブジェクトを配置 g.DrawImageUnscaled(bmp, x0 + tempX, y0 + tempY + 1); //Form1の座標(10,10)を基準点としてBitmapオブジェクトを配置 g.DrawImageUnscaled(bmp, x0 + tempX, y0 + tempY - 1); //Form1の座標(10,10)を基準点としてBitmapオブジェクトを配置 } private void Form1_Paint(object sender, PaintEventArgs e) { int i; Graphics g = e.Graphics; //原点:(x0,y0) g.DrawLine(Pens.Black, x0, y0, x0 + xMAX, y0); //横軸  中央:500 for (i = 0; i < 4; i++) //横軸目盛(90゜間隔) { g.DrawLine(Pens.Black, x0 + 250 * (i + 1), y0 - 10, x0 + 250 * (i + 1), y0 + 10); } g.DrawLine(Pens.Black, x0, y0 + yMAX, x0, y0 - yMAX); //原点の縦軸 for (i = 0; i < 2; i++) //縦軸目盛 50% { g.DrawLine(Pens.Black, x0 - 10, y0 + yMAX / (i + 1), x0 + 10, y0 + yMAX / (i + 1)); } for (i = 0; i < 2; i++) //縦軸目盛 50% { g.DrawLine(Pens.Black, x0 - 10, y0 - yMAX / (i + 1), x0 + 10, y0 - yMAX / (i + 1)); } } private void button1_Click(object sender, EventArgs e) //start { if (start_stop == false) //mmタイマが停止中の場合 { start_stop = true; button1.Text = "Stop"; mmtimer.timerStart(); //mmタイマをスタートさせる } else { start_stop = false; button1.Text = "Start"; mmtimer.timerStop(); //mmタイマを停止させる } } private void button2_Click(object sender, EventArgs e) //reset { total_time = 0; Count1000 = 0; pictureBox1.Refresh(); this.Refresh(); // フォームをクリアして、Form1_Paint() } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { mmtimer.timerStop(); //タイマ停止 Application.DoEvents(); //メッセージ キューにある Windows メッセージをすべて処理 } private void pictureBox1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; Font objFont = new Font("MS ゴシック", 40); String str = string.Format("{0:#,0}", total_time); g.DrawString(str, objFont, Brushes.Red, 0, 0); } } } //---------------------------------------------------------------------- //mmTimer.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; //API関数を使用する場合必要 namespace mmT_Sin { public class mmTimer //public を追加のこと defaultではpublicがない { Form1 form1; // Form1のオブジェクト生成 public IntPtr mmTimerID = (IntPtr)0;// マルチメディアタイマーのIDの宣言 // timeSetEventで指定するタイマーコールバック関数をデリゲートで定義 private delegate void TimerProcDelegate(IntPtr uID, int uMsg, mmTimer Inst, int dw1, int dw2); private TimerProcDelegate Proc = TimerProc; // TimerProcDelegate型にTimerProc関数を代入 private delegate void RefreshDelegate(); // マルチメディアタイマーのコールバック関数内で使用する関数をデリゲートで定義 private delegate void RefreshPictureDelegate(); // マルチメディアタイマーのコールバック関数内で使用する関数をデリゲートで定義 [DllImport("winmm.dll")] private extern static IntPtr timeSetEvent(int uDelay, int uResolution, TimerProcDelegate lpFunction, mmTimer mmT, int uFlags); //MMRESULT timeSetEvent( //VS SetTimer //UINT uDelay, //イベント遅延をミリ秒で指定します //UINT uResolution, //タイマイベントの分解能をミリ秒で指定します。 //LPTIMECALLBACK lpTimeProc, //コールバック関数のアドレスを指定します。 //DWORD dwUser, //ユーザーが提供するコールバックデータを指定します //UINT fuEvent //下記タイマイベントのタイプを指定します // //TIME_ONESHOT イベントは、uDelay ミリ秒経過後に 1 度発生します。 // //TIME_PERIODIC イベントは、uDelay ミリ秒ごとに発生します //); [DllImport("winmm.dll")] private extern static int timeKillEvent(IntPtr uID); //指定されたタイマイベントを停止します。 //MMRESULT timeKillEvent( // UINT uTimerID //停止するタイマのID //); [DllImport("winmm.dll")] private extern static int timeBeginPeriod(int uPeriod); //アプリケーションまたはデバイスドライバの最小タイマ分解能を、 //ミリ秒単位で指定します [DllImport("winmm.dll")] private extern static int timeEndPeriod(int uPeriod); //以前にセットされた最小タイマ分解能をクリアします。 public void timerStart() // タイマースタート { if (mmTimerID == (IntPtr)0) //lTimerEventID が 0(何も設定されていない)場合 → mmTimerが停止している場合 { timeBeginPeriod(1); //最少タイマ分解能を1msecに設定 mmTimerID = timeSetEvent(1, 0, Proc, this, 1); //インターバル時間:1msec、分解能:0(システムの最少)、 //コールバック関数のアドレス:Proc、1:TIME_PERIDIC   // mmTimerID = timeSetEvent(10, 0, Proc, this, 1); //インターバル時間:10msec、分解能: //0(システムの最少)、コールバック関数のアドレス:Proc、1:TIME_PERIDIC   } } public static void TimerProc( // マルチメディアタイマーコールバック関数 IntPtr uTimerID, //タイマID int uMsg, //メッセージを識別する整数 mmTimer mmT, //timeSetEvent( , , , SWModule Inst(第4引数), XX )の第4引数から渡されるユーザデータ // DWORD dwUser, // ユーザー定義 int dw1, //予約 int dw2 //予約 ) { if (mmT.mmTimerID == uTimerID) { mmT.form1.total_time += 1; // 1msec経過したとして +1をトータルタイムに加算 // mmT.form1.total_time++; // 1msec経過したとして +1をトータルタイムに加算 // mmT.form1.total_time += 10; // 10msec経過したとして +10をトータルタイムに加算 mmT.form1.Invoke(new RefreshDelegate(mmT.form1.Invoke_request)); //pictureBox1 リフレッシュ mmT.form1.Invoke(new RefreshPictureDelegate(mmT.form1.pictureBox1.Refresh)); //pictureBox1 リフレッシュ } } public void timerStop() { if (mmTimerID != (IntPtr)0) //mmTimerが 0でない場合 → 動作中の場合 { timeKillEvent(mmTimerID); //  タイマ停止 timeEndPeriod(1); //以前にセットされた最小タイマ分解能をクリア mmTimerID = (IntPtr)0; } } public void loadForm(Form1 Form1) // フォームオブジェクト格納 { form1 = (Form1)Form1; // } } }



■ 正弦波形描画 & D/A拡張キバンへの出力(1msec毎、マルチメディアタイマ)

・ 1msec_毎にマルチメディアタイマをもちいて正弦波形を描き また同時にPCの拡張スロット(PICバス)に追加したD/A拡張キバンの
 D/A出力端子に ピーク± 10Vで出力した例を紹介します。(→ プロジェクトファイル)
・ 拡張キバンはインターフェース梶@の D/A拡張キバン(PCI-3523A)です。


・ 実験回路外観

          

   <プログラム例>


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using InterfaceCorpDllWrap;

namespace mmT_Sin
{
    public partial class Form1 : Form
    {
        private bool start_stop;              //スタートストップ フラグ
        public long total_time = 0;             //累計msec
        public int Count1000 = 0;              //1sec
        private mmTimer mmtimer = new mmTimer();     // クラスmmTimerのインスタンス生成
        private int x0 = 100, y0 = 500; //原点座標
        private int xMAX = 1000, yMAX = 400;
        private int ColorFlag = 0;    //0:赤  1:青

        public IntPtr hSavedDevice;
        public IFCDA_ANY.DASMPLREQ gConfig;

  
        //デリゲートの宣言する
        delegate void MyDelegate();

        public Form1()
        {
            InitializeComponent();
            mmtimer.loadForm(this);
            mmtimer.mmTimerID = (IntPtr)0;   //mmタイマのIDを0に宣言
            start_stop = false;
            button1.Text = "Start";
            button2.Text = "Reset";

            this.WindowState = FormWindowState.Maximized;   //Windowフォームを最大化
        }

        public void Invoke_request()    //祈願によりデリゲートを呼出す、
        {
            Invoke(new MyDelegate(mmTUpdate));
        }

        public void mmTUpdate()     //1msec毎のコールバック
        {
            int tempX,tempY;
            double tempSin;

            uint Channel = 2;   // 2チャンネル :出力するチャンネル番号
            IFCDA_ANY.DASMPLCHREQ[] SmplChInf = new IFCDA_ANY.DASMPLCHREQ[2];
            ushort[] wData = new ushort[1];
            uint ulCh = 1;  //出力するチャンネル数
            int gnErrCode = -1;


            Graphics g = this.CreateGraphics(); //Form1へのGraphicsオブジェクトを作成
            Bitmap bmp = new Bitmap(1, 1); //サイズが1ドット×1ドットのBitmapオブジェクトを作成

            Count1000++;
            tempX = Count1000;
         
            if(Count1000 >= 1000)   
            {
                Count1000 = 0;

                if (ColorFlag == 1) ColorFlag = 0;
                else ColorFlag = 1;
            }

            if (ColorFlag == 0)
            {
                bmp.SetPixel(0, 0, Color.Blue);  //座標(0,0)を赤色に設定
            }
            else
            {
                bmp.SetPixel(0, 0, Color.Red);  //座標(0,0)を赤色に設定
            }


            tempX = Count1000;
            tempSin = Math.Sin(2 * Math.PI * tempX / 1000);
            tempY = (int)(yMAX * tempSin);

            g.DrawImageUnscaled(bmp, x0 + tempX, y0 + tempY); //Form1の座標(10,10)を基準点としてBitmapオブジェクトを配置
            g.DrawImageUnscaled(bmp, x0 + tempX, y0 + tempY + 1); //Form1の座標(10,10)を基準点としてBitmapオブジェクトを配置
            g.DrawImageUnscaled(bmp, x0 + tempX, y0 + tempY - 1); //Form1の座標(10,10)を基準点としてBitmapオブジェクトを配置

            SmplChInf[0].ulChNo = Channel; //チャンネル番号
            SmplChInf[0].ulRange = 0x00080000;  //出力モード バイポーラ:±10V

            wData[0] = (ushort)(2048 + 2047 * tempSin); //出力設定 

            gnErrCode = IFCDA_ANY.DaOutputDA(                   //DA出力関数                   
                                                hSavedDevice,   //ハンドル
                                                ulCh,           //出力するチャンネル数
                                                SmplChInf,      //DASAMPLCHREQ構造体のポインタ
                                                wData);         //主力データのポインタ

        }



        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            int i;
   
            Graphics g = e.Graphics;

            //原点:(x0,y0)
            g.DrawLine(Pens.Black, x0, y0, x0 + xMAX, y0);   //横軸  中央:500
            for (i = 0; i < 4; i++)     //横軸目盛(90゜間隔)
            {
                g.DrawLine(Pens.Black, x0 + 250 * (i + 1), y0 - 10, x0 + 250 * (i + 1), y0 + 10);
            }

            g.DrawLine(Pens.Black, x0, y0 + yMAX, x0, y0 - yMAX);  //原点の縦軸
            for (i = 0; i < 2; i++)     //縦軸目盛 50%
            {
                g.DrawLine(Pens.Black, x0 - 10, y0 + yMAX / (i + 1), x0 + 10, y0 + yMAX / (i + 1));
            }

            for (i = 0; i < 2; i++)     //縦軸目盛 50%
            {
                g.DrawLine(Pens.Black, x0 - 10, y0 - yMAX / (i + 1), x0 + 10, y0 - yMAX / (i + 1));
            }
        }

        private void button1_Click(object sender, EventArgs e)  //start
        {



            if (start_stop == false)    //mmタイマが停止中の場合
            {
                start_stop = true;
                button1.Text = "Stop";
                mmtimer.timerStart();                //mmタイマをスタートさせる

                string szDeviceName = "FBIDA1";
                hSavedDevice = IFCDA_ANY.DaOpen(szDeviceName);
            }
            else
            {
                start_stop = false;
                button1.Text = "Start";
                mmtimer.timerStop();              //mmタイマを停止させる
                IFCDA_ANY.DaClose(hSavedDevice);                // Closes a device.
            }

        }

        private void button2_Click(object sender, EventArgs e)  //reset
        {
            total_time = 0;
            Count1000 = 0;
            pictureBox1.Refresh();
               
            this.Refresh(); // フォームをクリアして、Form1_Paint()

            

         


           
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
                mmtimer.timerStop();        //タイマ停止
                Application.DoEvents();     //メッセージ キューにある Windows メッセージをすべて処理

        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            Font objFont = new Font("MS ゴシック", 40);
            String str = string.Format("{0:#,0}", total_time);
            g.DrawString(str, objFont, Brushes.Red, 0, 0);
        }
    }
}






//---------------------------------------------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;   //API関数を使用する場合必要

namespace mmT_Sin
{
    public class mmTimer    //public を追加のこと defaultではpublicがない
    {
        Form1 form1;  // Form1のオブジェクト生成

        public IntPtr mmTimerID = (IntPtr)0;// マルチメディアタイマーのIDの宣言

        // timeSetEventで指定するタイマーコールバック関数をデリゲートで定義
        private delegate void TimerProcDelegate(IntPtr uID, int uMsg, mmTimer Inst, int dw1, int dw2);
        private TimerProcDelegate Proc = TimerProc;  // TimerProcDelegate型にTimerProc関数を代入
        private delegate void RefreshDelegate(); // マルチメディアタイマーのコールバック関数内で使用する関数をデリゲートで定義

        private delegate void RefreshPictureDelegate(); // マルチメディアタイマーのコールバック関数内で使用する関数をデリゲートで定義
  

        [DllImport("winmm.dll")]
        private extern static IntPtr timeSetEvent(int uDelay, int uResolution, TimerProcDelegate lpFunction, mmTimer mmT, int uFlags);
        //MMRESULT timeSetEvent(         //VS SetTimer
        //UINT uDelay,   //イベント遅延をミリ秒で指定します
        //UINT uResolution,     //タイマイベントの分解能をミリ秒で指定します。
        //LPTIMECALLBACK lpTimeProc,    //コールバック関数のアドレスを指定します。
        //DWORD dwUser,         //ユーザーが提供するコールバックデータを指定します
        //UINT fuEvent      //下記タイマイベントのタイプを指定します
        //                  //TIME_ONESHOT      イベントは、uDelay ミリ秒経過後に 1 度発生します。
        //                  //TIME_PERIODIC     イベントは、uDelay ミリ秒ごとに発生します
        //);

        [DllImport("winmm.dll")]
        private extern static int timeKillEvent(IntPtr uID);        //指定されたタイマイベントを停止します。
        //MMRESULT timeKillEvent(
        //  UINT uTimerID       //停止するタイマのID
        //);

        [DllImport("winmm.dll")]
        private extern static int timeBeginPeriod(int uPeriod); //アプリケーションまたはデバイスドライバの最小タイマ分解能を、ミリ秒単位で指定します

        [DllImport("winmm.dll")]
        private extern static int timeEndPeriod(int uPeriod);   //以前にセットされた最小タイマ分解能をクリアします。


        public void timerStart()   // タイマースタート
        {
            if (mmTimerID == (IntPtr)0) //lTimerEventID が 0(何も設定されていない)場合 → mmTimerが停止している場合
            {
                timeBeginPeriod(1);    //最少タイマ分解能を1msecに設定

                mmTimerID = timeSetEvent(1, 0, Proc, this, 1); //インターバル時間:1msec、分解能:0(システムの最少)、コールバック関数のアドレス:Proc、1:TIME_PERIDIC  
                //              mmTimerID = timeSetEvent(10, 0, Proc, this, 1); //インターバル時間:10msec、分解能:0(システムの最少)、コールバック関数のアドレス:Proc、1:TIME_PERIDIC  

            }
        }

        public static void TimerProc(       // マルチメディアタイマーコールバック関数
        IntPtr uTimerID,    //タイマID
        int uMsg,           //メッセージを識別する整数
        mmTimer mmT,      //timeSetEvent( , , , SWModule Inst(第4引数), XX )の第4引数から渡されるユーザデータ    // DWORD dwUser, // ユーザー定義
        int dw1,    //予約
        int dw2     //予約
        )
        {
            if (mmT.mmTimerID == uTimerID)
            {

                mmT.form1.total_time += 1;   // 1msec経過したとして +1をトータルタイムに加算

                //   mmT.form1.total_time++; // 1msec経過したとして +1をトータルタイムに加算
                //                mmT.form1.total_time += 10; // 10msec経過したとして +10をトータルタイムに加算

                mmT.form1.Invoke(new RefreshDelegate(mmT.form1.Invoke_request));     //pictureBox1 リフレッシュ

                mmT.form1.Invoke(new RefreshPictureDelegate(mmT.form1.pictureBox1.Refresh));     //pictureBox1 リフレッシュ


            }
        }



        public void timerStop()
        {

            if (mmTimerID != (IntPtr)0) //mmTimerが 0でない場合 → 動作中の場合
            {
                timeKillEvent(mmTimerID);   //  タイマ停止                                           
                timeEndPeriod(1); //以前にセットされた最小タイマ分解能をクリア
                mmTimerID = (IntPtr)0;
            }


        }

        public void loadForm(Form1 Form1) // フォームオブジェクト格納
        {
            form1 = (Form1)Form1;   //
        }



    }
}



//------------------------------------------------------------------------------------------------------------------------------------------




 

D/A出力端子電圧波形
(拡張キバン: PCI-3523A  AD12ビット8CH /DA12ビット4CH(±10V))

正弦波マクロ波形(5V/div 250msec/div)   正弦波ミクロ波形(100mV/div 1msec/div)
デジタルオシロスコープ
ATTEN製(中国) ADS1102CA