卒研の成果物

を以前公開するよと予告したので、今日思い立って公開します。ソースコードだけ。
700行程度、タートル工業社製のUSB AD/DAコンバータをVBを使って制御する参考例です。

'_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
'Program name:DA-AD-converter
'Date:2011/04/04(Program start)
'Name:raiden(E-mail address:gozen3.25(at)gmail.com)
'Status:During an experimet
'Purpuse:新型リニアボールガイド実験用プログラム
'Note:TUSB-0216ADMH and TUSB-0212DAMA
'2011/08/25 フィードバック制御対応(比例制御のみ、積分、微分は随時対応予定)
'2011/11/22 高精度時間制御対応(フィードバック制御と実行時間の高精度化)
'2011/12/14 1[ms]でのフィードバック対応。ただし、AD変換データがない場合は
'            フィードバック処理がされない。
'_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
Imports System
Imports System.Diagnostics
Imports System.Threading
Public Class Form1
    'ローカル変数
    Private flag As Byte = 0	'実行時間終了フラグ
    Private adid As Byte '= adcid.SelectedItem      'adcのID
    Dim daid As Byte '= dacid.SelectedItem       'dacのID
    Private data2(100000) As integer  'adcから取得したデータ
    'メイン関数関連変数
    Dim err As Byte = 0	'エラーフラグ
    Dim wave As String '= outputwave.SelectedItem     '出力波形
    Dim Kp, Ti, voltage, voltrange, goal As Single
    Dim time As Integer = 1	'実行時間
    Dim daerr As Byte = 0    'dacのエラー
    Dim aderr As Byte = 0    'adcのエラー
    Dim outputdata As Short = 0
    Dim signal As Byte = 2
    Dim channel As Integer = 0
    Dim range As Integer = 0
    Dim n As Integer = 0
    Dim data1(8200) As Integer      'dacから出力する正弦波のデータ8200
    Dim leng As Long
	Dim cerr As Integer		'フィードバックエラー回数
    Dim ad_enable As Byte = 0
    Dim da_enable As Byte = 0
    Dim path As String
    Dim kouseikeisu As Single = 0.2086
    Dim fcnt As Integer = 0
    Dim voltage1 As Single = 0
    Dim initvolt As Single = 0
    Dim volt As Single = 0

    '関数宣言
    Declare Function timeGetTime Lib "winmm.dll" Alias "timeGetTime" () As Long '現在の時刻を取得
    Declare Function timeBeginPeriod Lib "winmm.dll" Alias "timeBeginPeriod" (ByVal uPeriod As Long) As Long    '時間精度を高くする
    Declare Function timeEndPeriod Lib "winmm.dll" Alias "timeEndPeriod" (ByVal uPeriod As Long) As Long
    Private Sub Wait(ByVal waittime As Long) 'waittime m秒待つ、timeGetTimeの精度は約1ms
        Dim starttime As Long
        'Dim mmresult As Integer
		'timeGetTime関数の精度をあげるためにはtimeBeginPeriod関数を使うが有効になるまでに時間がかかる。
        'mmresult = timeBeginPeriod(1)
        starttime = timeGetTime() '現在の時刻を取得

        Do While timeGetTime() - starttime < waittime '現在の時刻-starttimeが待ち時間を上回ったらループからぬける
            Application.DoEvents()
        Loop
		'timeGetTime関数の使用後はただちにtimeEndPriod関数を使う
        'mmresult = timeEndPeriod(1)
    End Sub
    'dacエラーチェック関数 dacerrchk(dacerr)
    Private Sub dacerrchk(ByVal dacerr As Integer)
        Select Case dacerr
            Case Is = 1
                MessageBox.Show("DACエラー! コード1:オープンされていません。")
            Case Is = 2
                MessageBox.Show("DACエラー! コード2:失敗しました。")
            Case Is = 3
                MessageBox.Show("DACエラー! コード3:設定値が不正です。")
        End Select
    End Sub
    'adcエラーチェック関数 adcerrchk(adcerr)
    Private Sub adcerrchk(ByVal adcerr As Integer)
        Select Case adcerr
            Case Is = 1
                MessageBox.Show("ADCエラー! コード1:IDが異なっています。")
            Case Is = 2
                MessageBox.Show("ADCエラー! コード2:ドライバが正常にインストールされていません。")
            Case Is = 4
                MessageBox.Show("ADCエラー! コード4:接続台数が多すぎます。")
            Case Is = 5
                MessageBox.Show("ADCエラー! コード5:デバイスをオープンできませんでした。")
            Case Is = 6
                MessageBox.Show("ADCエラー! コード6:指定のデバイスが見つかりません。")
            Case Is = 7
                MessageBox.Show("ADCエラー! コード7:指定のデバイスはオープンされていません。")
            Case Is = 8
                MessageBox.Show("ADCエラー! コード8:指定パラメータのエラーです。")
            Case Is = 9
                MessageBox.Show("ADCエラー! コード9:USB通信エラーです。")
            Case Is = 10
                MessageBox.Show("ADCエラー! コード10:メモリが確保できません。")
            Case Is = 11
                MessageBox.Show("ADCエラー! コード11:連続取り込み動作中です")
            Case Is = 12
                MessageBox.Show("ADCエラー! コード12:連続取り込みデータはありません。")
            Case Is = 13
                MessageBox.Show("ADCエラー! コード13:連続取り込みが開始されていません。")
            Case Is = 14
                MessageBox.Show("ADCエラー! コード14:メモリがオーバーフローしました。")
            Case Is = 15
                MessageBox.Show("ADCエラー! コード15:データ列順エラーです。")
            Case Is = 99
                MessageBox.Show("ADCエラー! コード99:その他のエラーです。")
        End Select
    End Sub
    '機能制限関数 function_enable_da(),function_enablead(),function_disable_da(),function_disable_ad()
    Private Sub function_enable_da()
        'オープン、ID選択可
        dacopen.Enabled = True
        dacid.Enabled = True
        dacclose.Enabled = False
    End Sub
    Private Sub function_disable_da()
        'オープン、ID選択不可
        dacopen.Enabled = False
        dacid.Enabled = False
        dacclose.Enabled = True
    End Sub
    Private Sub function_enable_ad()
        'オープン、ID選択可
        adcopen.Enabled = True
        adcid.Enabled = True
        adcclose.Enabled = False
    End Sub
    Private Sub function_disable_ad()
        'オープン、ID選択不可
        adcopen.Enabled = False
        adcid.Enabled = False
        adcclose.Enabled = True
    End Sub
    private sub execute_enable()
		'実行ボタンを押せるようにする。
        If da_enable = 1 Then
            If ad_enable = 1 Then
                da_enable = 0
                ad_enable = 0
                Button1.Enabled = True
                'Button5.Enabled = True
                'Button2.Enabled = True
            End If
        Else
            Button1.Enabled = False
            'Button5.Enabled = False
            'Button2.Enabled = False
        End If
    End Sub
    '設定入力関数 settings()
    Private Sub settings()
        cerr = 0
        time = Val(TextBox5.Text)
        voltage = Val(TextBox2.Text)
        goal = voltage
        Kp = Val(TextBox3.Text)
        Ti = Val(TextBox4.Text)
        leng = 1048576
        wave = outputwave.SelectedItem
        'ラジオボタンチェック
        If RadioButton1.Checked Then
            'ユニポーラに設定
            signal = 0
        ElseIf RadioButton2.Checked Then
            'バイポーラに設定
            signal = 1
        Else
            err = 1
            MessageBox.Show("エラー3(出力方法が設定されていません。)")
        End If
        'チャンネルチェック
        If usech.SelectedItem = "OUT1" Then
            channel = 1
        ElseIf usech.SelectedItem = "OUT2" Then
            channel = 2
        Else
            err = 1
            MessageBox.Show("エラー19(チャンネルが設定されていません。)")
        End If
        '出力電圧レベルチェック
        If RadioButton3.Checked Then
            Select Case signal
                'バイポーラ設定
                Case Is = 1
                    If voltage <= 5 Then
                        range = 0
                        voltrange = 5
                        '電圧をデジタル値に変換
                        If voltage <= 2.5 Then
                            outputdata = voltage / (2.5 / 2048)
                        ElseIf voltage <= 5 Then
                            outputdata = (voltage - 2.5) / ((4.999 - 2.5) / 2047) + 2047
                        End If
                    Else
                        err = 1
                        MessageBox.Show("エラー21(設定に不正があります。)")
                    End If
                    'ユニポーラ設定
                Case Is = 0
                    If voltage <= 2.5 Then
                        range = 0
                        voltrange = 2.5
                        outputdata = voltage / (2.5 / 2047) + 2048
                        'outputdata = voltage / (2.5 / 4095)
                    Else
                        err = 1
                        MessageBox.Show("エラー21(設定に不正があります。)")
                    End If
                Case Is = 2
                    err = 1
            End Select
        ElseIf RadioButton4.Checked Then
            Select Case signal
                'バイポーラ設定
                Case Is = 1
                    If voltage <= 10 Then
                        range = 1
                        voltrange = 10
                        If voltage <= 5 Then
                            outputdata = voltage / (2.5 / 2048)
                        ElseIf voltage <= 10 Then
                            outputdata = (voltage - 5) / ((9.996 - 5) / 2047) + 2046
                        End If
                    Else
                        err = 1
                        MessageBox.Show("エラー21(設定に不正があります。)")
                    End If
                    'ユニポーラ設定
                Case Is = 0
                    If voltage <= 5 Then
                        range = 1
                        voltrange = 5
                        outputdata = voltage / (5 / 2047) + 2048
                        'outputdata = voltage / (5 / 4095)
                    Else
                        err = 1
                        MessageBox.Show("エラー21(設定に不正があります。)")
                    End If
                Case Is = 2
                    err = 1
            End Select
        ElseIf RadioButton5.Checked Then
            Select Case signal
                'バイポーラ設定
                Case Is = 1
                    err = 1
                    MessageBox.Show("エラー21(設定に不正があります。)")
                    'ユニポーラ設定
                Case Is = 0
                    If voltage <= 10 Then
                        range = 2
                        voltrange = 10
                        outputdata = voltage / (9.995 / 2047) + 2047
                        'outputdata = voltage / (9.995 / 4095)
                    Else
                        err = 1
                        MessageBox.Show("エラー21(設定に不正があります。)")
                    End If
                Case Is = 2
                    err = 1
            End Select
        Else
            err = 1
            MessageBox.Show("エラー20(出力電圧レベルが設定されていません。)")
        End If
        'ADクロック設定(クロック1MHz) メモリに格納されるデータ数=本来のデータ数/平均化回数
        aderr = Tusbadmh_Clock_Select(adid, 0, 199, 8)
        If aderr <> 0 Then
            'aderr = Tusbadmh_Clock_Select(adid, 0, 49, 8)
            adcerrchk(aderr)
            err = 1
            Tusbadmh_Unload()
        End If
        'アナログトリガ設定
        aderr = Tusbadmh_ThLevel_Set(adid, 32767, 800)
        If aderr <> 0 Then
            'aderr = Tusbadmh_ThLevel_Set(adid, 32767, 800)
            adcerrchk(aderr)
            err = 1
            Tusbadmh_Unload()
        End If
    End Sub
    'DA設定関数 sin_set(fcnt)
    Private Sub sin_set(ByVal fcnt As Integer)
        For i = 1 To 10 Step 1
            '2048*電圧/出力電圧レベル=振幅
            data1(i) = 2048 * (voltage / 5) * Math.Sin(2 * Math.PI * (i + 10 * fcnt) / 1700) + 2048 + 2048 * (voltage1 / 5)
            'data1(i) = 2048 * (voltage / 2.5) * Math.Sin(2 * Math.PI * (i + 10 * fcnt) / 2000) + 2048 + 2048 * (voltage1 / 2.5)
            If data1(i) > 4095 Then
                data1(i) = 4095
            ElseIf data1(i) < 0 Then
                data1(i) = 0
            End If
        Next
        daerr = Tusbdam_Set_Memory(daid, channel, 10, data1(1))
        If daerr <> 0 Then
            'エラー
            dacerrchk(daerr)
            err = 1
            console.Text &= "エラーが発生したため実行を中断します..." & vbCrLf
            Tusbadmh_Unload()
            Tusbdam_Device_Close(daid)
            Exit Sub
        End If
    End Sub
    'feedback関数
    Private Sub feedback()
        Dim D1 As Single    '目標値
        Dim D2 As Single    '変換データ
        If Tusbadmh_Data_Get(adid, 0, data2(1), leng) <> 0 Then '***DLL関数の実行
            MessageBox.Show("DLL関数の実行に失敗しました。デバイスをクローズします。") '***書きこみに失敗
            Tusbadmh_Unload()
            err = 1
        End If
        If leng <> 0 Then
            D1 = goal * Math.Sin(2 * Math.PI * (10 + 10 * fcnt) / 1700)
            D2 = (((data2(leng) - 32768) / 32768) / kouseikeisu) - initvolt
            'フィードバック
            volt = D1 - D2
            If voltage1 > voltrange Then
                voltage1 = voltrange
            End If
        Else
            cerr = cerr + 1
        End If
        leng = 1048576
    End Sub
    'DA出力関数 output()
    Private Sub output()
        console.Text &= Now & vbCrLf & "機器設定" & vbCrLf & "実行時間(秒):" & time & vbTab & vbTab & vbCrLf & "条件設定" & vbCrLf & "電圧:" & voltage & vbTab & "比例ゲインKp:" & Kp & vbTab & "積分時間Ti:" & Ti & vbTab & "出力波形:" & wave & vbCrLf
        Select Case wave
            Case Is = "step"
                '出力波形:ステップ(step)                    
                Timer1.Enabled = True
                Timer1.Interval = time * 1000
                Timer1.Start()
                'ad変換設定
                daerr = Tusbdam_Single_Out(daid, channel, outputdata)
                If daerr <> 0 Then
                    'エラー
                    'daerr = Tusbdam_Single_Out(daid, channel, outputdata)
                    dacerrchk(daerr)
                    err = 1
                    console.Text &= "エラーが発生したため実行を中断します..." & vbCrLf
                    Tusbadmh_Unload()
                    Tusbdam_Device_Close(daid)
                    Exit Sub
                End If
                console.Text &= "実行します..." & vbCrLf
                Do Until flag = 1
                    My.Application.DoEvents()       '実行中に発生する他の処理を可能にする
                    If err = 1 Then
                        Timer1.Stop()
                        Timer1.Enabled = False
                        flag = 0
                        Exit Do
                    End If
                Loop
                '終了処理
                Timer1.Stop()
                Timer1.Enabled = False
                'Timer2.Stop()
                'Timer2.Enabled = False
                Tusbdam_Stop(daid)
                'console.Text &= time & "秒経過しました。" & vbCrLf
            Case Is = "sin"
                '出力波形:正弦波(sin)
                daerr = Tusbdam_Clock_Set(daid, 1, 2)   'da内部クロック、2MHz(最高)
                If daerr <> 0 Then
                    'エラー
                    'daerr = Tusbdam_Clock_Set(daid, 1, 2)   '内部クロック
                    dacerrchk(daerr)
                    err = 1
                    console.Text &= "エラーが発生したため実行を中断します..." & vbCrLf
                    Tusbadmh_Unload()
                    Tusbdam_Device_Close(daid)
                    Exit Sub
                End If
                fcnt = 0
                'sin_set(fcnt)        '正弦波の設定
                daerr = Tusbdam_Cycle_Set(daid, 10)       'daデータ数と同じにする
                If daerr <> 0 Then
                    'エラー
                    'daerr = Tusbdam_Cycle_Set(daid, 1000)
                    dacerrchk(daerr)
                    err = 1
                    console.Text &= "エラーが発生したため実行を中断します..." & vbCrLf
                    Tusbadmh_Unload()
                    Tusbdam_Device_Close(daid)
                    Exit Sub
                End If
                aderr = Tusbadmh_InputType(adid, 0, 0)
                If aderr <> 0 Then
                    'エラー
                    'aderr = Tusbadmh_InputType(adid, 0, 0)
                    adcerrchk(aderr)
                    err = 1
                    console.Text &= "エラーが発生したため実行を中断します..." & vbCrLf
                    Tusbadmh_Unload()
                    Tusbdam_Device_Close(daid)
                    Exit Sub
                End If
                console.Text &= "実行を開始します..." & vbCrLf
                aderr = Tusbadmh_Adc_Start(adid, 100000, 0, 3, 0, 0)      '1:ユニポーラ,0:バイポーラ,1トリガあたりの取り込み長
                If aderr <> 0 Then
                    'エラー
                    adcerrchk(aderr)
                    err = 1
                    console.Text &= "エラーが発生したため実行を中断します..." & vbCrLf
                    Tusbadmh_Unload()
                    Tusbdam_Device_Close(daid)
                    Exit Sub
                End If
                'ソフトウェアトリガ
                aderr = Tusbadmh_Trigger(adid)
                If aderr <> 0 Then
                    adcerrchk(aderr)
                    err = 1
                    console.Text &= "エラーが発生したため実行を中断します..." & vbCrLf
                    Tusbadmh_Unload()
                    Tusbdam_Device_Close(daid)
                    Exit Sub
                End If
                '初期電圧を測定する
                Wait(10)
                If Tusbadmh_Data_Get(adid, 0, data2(1), leng) <> 0 Then '***DLL関数の実行
                    MessageBox.Show("DLL関数の実行に失敗しました。デバイスをクローズします。") '***書きこみに失敗
                    Tusbadmh_Unload()
                    err = 1
                End If
                initvolt = ((data2(leng) - 32768) / 32768) / kouseikeisu
                console.Text &= initvolt & vbCrLf & "取り込みデータ長=" & leng & vbCrLf
                leng = 1048576
				'HIOKIと同期
                Tusbdam_Set_Memory(daid, channel, 10, 4095)
                Tusbdam_Start(daid, 2)
				'wait(10)
				'Tusbdam_Set_Memory(daid, 2, 1, 2184)
				'Tusbdam_Start(daid, 2)
				'Tusbdam_stop(adid)
                'Dim stopWatch As New Stopwatch()
                'timer1:時間計測
                Timer1.Enabled = True
                Timer1.Interval = time * 1000
                'Timer2.Enabled = True
                'Timer2.Interval = 1
                'Timer2.Start()
                Timer1.Start()
                'stopWatch.Start()
                'フィードバック用スレッド
                BackgroundWorker1.RunWorkerAsync()
                Do Until flag = 1
                    My.Application.DoEvents()        '実行中に発生する他の処理を可能にする
                    If err = 1 Then
                        Timer1.Stop()
                        Timer1.Enabled = False
                        flag = 0
                        'Timer2.Stop()
                        'Timer2.Enabled = False
                        Exit Do
                    End If
                    Select Case signal
                        'ユニポーラ
                        Case Is = 0
                            MessageBox.Show("エラー21(設定に不正があります。)")
                            flag = 0
                            Timer1.Stop()
                            Timer1.Enabled = False
                            'Timer2.Stop()
                            'Timer2.Enabled = False
                            err = 1
                            Exit Do
                            'バイポーラ
                        Case Is = 1
                            'fcntは100000なら1データあたり1000であれば1000*fcntを足すからfcnt=99にすればよい
                            For i = 0 To 169 Step 1
                                sin_set(fcnt)
                                daerr = Tusbdam_Start(daid, 0)
                                If daerr <> 0 Then
                                    dacerrchk(daerr)
                                    err = 1
                                    console.Text &= "エラーが発生したため実行を中断します..." & vbCrLf
                                    Tusbadmh_Unload()
                                    Tusbdam_Device_Close(daid)
                                    Exit Sub
                                End If
                                'フィードバックされたデータを反映
                                If volt <> voltage1 Then
                                    voltage1 = volt
                                End If
                                fcnt = fcnt + 1
                                '時間経過か緊急停止ボタン(エラー)が押されたらexit doで終了する
                                If flag = 1 Or err = 1 Then
                                    Exit Do
                                End If
                            Next
                            fcnt = 0
                    End Select
                Loop
                '出力終了
                'stopWatch.Stop()
                Timer1.Stop()
                Timer1.Enabled = False
                'Timer2.Stop()
                'Timer2.Enabled = False
                Tusbdam_Stop(daid)
                Tusbadmh_Adc_Stop(adid)
                'console.Text &= stopWatch.ElapsedMilliseconds & "ミリ秒経過しました。" & vbCrLf
        End Select
    End Sub
    '終了処理関数 shutdown()
    Private Sub shutdown()
        Select Case wave
            Case Is = "step"
                '0Vを出力しなおす
                Select Case signal
                    Case Is = 0     'ユニポーラ
                        Tusbdam_Single_Out(daid, channel, 0)
                    Case Is = 1     'バイポーラ
                        Tusbdam_Single_Out(daid, channel, 2048)
                End Select
                flag = 0
            Case Is = "sin"
                '0Vを出力しなおす
                Select Case signal
                    Case Is = 0
                        Tusbdam_Single_Out(daid, channel, 0)
                    Case Is = 1
                        Tusbdam_Single_Out(daid, channel, 2048)
                End Select
                flag = 0
        End Select
    End Sub
    'エラーチェック関数 errorcheck()
    Private Sub errorcheck()
        'adcが使用できるか?
        aderr = Tusbadmh_Chk(adid)
        If aderr <> 0 Then
            'aderr = Tusbadmh_Chk(adid)
            adcerrchk(aderr)
            err = 1
            Tusbadmh_Unload()
        End If
        'If (voltrange = 2.5 & signal = 0) Then
        'err = 1
        'console.Text = "エラーが発生したため実行を中断します..." & vbCrLf
        'Tusbadmh_Unload()
        'Tusbdam_Device_Close(daid)
        'End If
        '出力電圧レベル設定
        daerr = Tusbdam_Range_Set(daid, channel, signal, range)
        If daerr <> 0 Then
            err = 1
            'daerr = Tusbdam_Range_Set(daid, channel, signal, range)
            dacerrchk(daerr)
            Tusbdam_Device_Close(daid)
        End If
        'エラーチェック
        If wave = "" Then
            MessageBox.Show("エラー2(出力波形が設定されていません。)")
            err = 1
        End If
    End Sub
    'メイン関数
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        '実行ルーチン
		'緊急停止ボタン以外を使用不可にする
		Button1.Enabled = False
		Button2.Enabled = False
		Button3.Enabled = False
		Button4.Enabled = False
		'高精度時間制御を可能にする
        Call timeBeginPeriod(1)
        err = 0
        path = ""
        console.Text &= "実行準備中..." & vbCrLf

        settings()
        errorcheck()
        'エラーが発生した場合実行しない
        If err = 0 Then
            Dim result As DialogResult = MessageBox.Show("実行します。可能な限り変位センサを0Vに近づけて、OKをクリックしてください。" ,"注意" , MessageBoxButtons.OKCancel)
            If result = DialogResult.OK Then
                'console.Text &= "測定値,設定値,目標値" & vbCrLf
                shutdown()
                output()
            	shutdown()
            	console.Text &= "フィードバックエラー回数:" & cerr & vbCrLf
            	MessageBox.Show(time & "秒経過しました。")
            ElseIf result = DialogResult.Cancel Then
            	MessageBox.Show("実行を中止しました。")
                shutdown()
            End If
        ElseIf err = 1 Then
            shutdown()
            MessageBox.Show("エラーが発生したため実行を中止します。")
            Tusbdam_Device_Close(daid)
            Tusbadmh_Unload()
        End If
		'高精度時間制御を不可にする
        Call timeEndPeriod(1)
        'ボタン有効化
		Button1.Enabled = True
		Button2.Enabled = True
		Button3.Enabled = True
		Button4.Enabled = True
		'For i = 1 To 100 Step 1
        'Next
        'shutdown()
    End Sub
    '終了
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        End
    End Sub
    '保存
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        '保存ルーチン
        Dim sfd As New SaveFileDialog()
        sfd.Filter = "テキストファイル(*.log)|*.log|全てのファイル(*.*)|*.*"
        '[ファイルの種類]ではじめに
        '「テキストファイル」が選択されているようにする
        sfd.FilterIndex = 1
        'タイトルを設定する
        sfd.Title = "保存先のファイルを選択してください。"
        'ダイアログボックスを閉じる前に現在のディレクトリを復元するようにする
        sfd.RestoreDirectory = True
        '既に存在するファイル名を指定したとき警告する
        'デフォルトでTrueなので指定する必要はない
        sfd.OverwritePrompt = True
        '存在しないパスが指定されたとき警告を表示する
        'デフォルトでTrueなので指定する必要はない
        sfd.CheckPathExists = True

        'ダイアログを表示する
        If sfd.ShowDialog() = DialogResult.OK Then
            Dim Writer As New IO.StreamWriter(sfd.FileName, True, System.Text.Encoding.GetEncoding("Shift-JIS"))
            Writer.Write(console.Text)
            Writer.Close()
            MessageBox.Show("保存しました。")
        End If
    End Sub
    'textboxクリア
    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        'messageboxクリア処理
        console.Text = ""
    End Sub
    'Form1を閉じたとき
    Private Sub Form1_Closed(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Closed
        If Timer2.Enabled Then 'タイマー2が動作中であれば
            Timer2.Enabled = False
        End If
        If Timer1.Enabled Then
            Timer1.Enabled = False 'タイマー1を停止します
        End If
        'デバイスのクローズ
        Tusbdam_Device_Close(daid)
        Tusbadmh_Unload()
    End Sub
    '実行時間の計測
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        'タイマー終了フラグを1にする
        flag = 1
        err = 1
        Timer1.Enabled = False
        Timer1.Stop()
        Timer2.Enabled = False
        Timer2.Stop()
		shutdown()
    End Sub
    '割り込み処理(AD変換データの書き込み)
    Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
        'マルチスレッド
        'BackgroundWorker1.RunWorkerAsync()
    End Sub
    'マルチスレッド
    Private Sub backgroundworker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        ' BackgroundWorkerの取得(スレッドを作成したオブジェクト)
        Dim objWorker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)
        '出力開始まで待機
		wait(2)
		'フィードバック
        Do Until err = 1
            Wait(10)
            feedback()
        Loop
    End Sub
    Private Sub backgroundworker_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        '何もしない
    End Sub
    'DACオープン
    Private Sub dacopen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dacopen.Click
        Dim dacerr As Integer
        daid = dacid.SelectedItem
        console.Text &= "DAコンバータをオープンします..."
        dacerr = Tusbdam_Device_Open(daid)
        If dacerr = 0 Then
            console.Text &= "使用できる状態になりました。" & vbCrLf
            function_disable_da()
            da_enable = 1
        Else
            'エラーの場合
            dacerrchk(dacerr)
        End If
        execute_enable()
    End Sub
    'ADCオープン
    Private Sub adcopen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles adcopen.Click
        Dim i As Integer = 0
        Dim adcerr As Integer
        adid = adcid.SelectedItem
        console.Text &= "ADコンバータをオープンします..."
        Tusbadmh_Load()
        While i < 10
            Wait(500) '500ms待つ
            adcerr = Tusbadmh_Chk(adid)
            If Tusbadmh_Chk(adid) = 0 Then 'エラーチェック
                i = 10 'ループをぬける
                function_disable_ad()
                console.Text &= "使用できる状態になりました。" & vbCrLf
                ad_enable = 1
            End If
            i = i + 1
        End While
        If adcerr <> 0 Then
            'エラーの場合
            adcerrchk(adcerr)
        End If
        execute_enable()
    End Sub
    'DACクローズ
    Private Sub dacclose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dacclose.Click
        Tusbdam_Device_Close(dacid.SelectedItem)
        function_enable_da()
        da_enable = 0
        execute_enable()
    End Sub
    'ADCクローズ
    Private Sub adcclose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles adcclose.Click
        Tusbadmh_Unload()
        function_enable_ad()
        ad_enable = 0
        execute_enable()
    End Sub
    '起動時の処理
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        function_enable_da()
        function_enable_ad()
        execute_enable()
        'Button2.Enabled = false     '保存ボタン無効
    End Sub
    '緊急停止
    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
        '緊急停止
        Timer1.Stop()
        Timer1.Enabled = False
        Timer2.Stop()
        Timer2.Enabled = False
        Tusbdam_Stop(daid)
        Tusbadmh_Adc_Stop(adid)
		shutdown()
		err=1
		Messagebox.show("実行を中断しました。")
		'ボタン有効化
		Button1.Enabled = True
		Button2.Enabled = True
		Button3.Enabled = True
		Button4.Enabled = True
	End Sub
End Class

卒研の成果物(C/C++ version)

一応、C/C++でも作ってあるので、そちらも公開しておかないと、と思い今更ながら公開。
動作未検証です。簡単なデバックはしていますが、動作保証しませんので。

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//Program name:DA-AD-Converter
//Date:2011/12/17(Programing start)
//Name:raiden(E-mail address:gozen3.25(at)gmail.com)
//Status:During as experiment
//Purpuse:Control program for the linear guide
//Version:0.1
//Note:TUSB-0216ADMH and TUSB-0212DAM
//
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#include <stdio.h>
#include "stdafx.h"
#include <math.h>
#include <conio.h>
//画面のクリアするヘッダー
#include <stdlib.h>
//割り込み関連のヘッダー
//参考URL:http://www.mint.se.ritsumei.ac.jp/contest/text/6/VCtimer.html
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")
//TUSB-0216ADMHのヘッダーファイル
//#include <TUSBADMH.h>
//TUSB-0212DAMのヘッダーファイル
//#include <TUSBDAM.h>

//グローバル変数設定
double voltage = 0;
//double voltage1 = 0;
int channel = 1;
double Kp = 0;
double Ti = 0;
int time = 0;
int type = 0;
int cerr = 0;

//定数宣言
const double kouseikeisu = 0.2086;

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//タイマー割り込み(実行時間計測)
//
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
void CALLBACK timerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dummy1, DWORD dummy2){
		// タイマー割り込みの処理
		(*(int*)dwUser)++;
		return;
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//タイマー割り込み(フィードバック)
//
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
void CALLBACK timerFeedback(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dummy1, DWORD dummy2){
		// タイマー割り込みの処理
		//feedback();
		return;
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//DAコンバータエラーチェック関数
//daerrchk(int dacerr)
//引数1:dacerr daのエラー
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
int daerrchk(int dacerr){
	switch(dacerr){
		case 1: printf("DA converter error! Code1:Is not open.\n");
			break;
		case 2: printf("DA converter error! Code2:Has failed.\n");
			break;
		case 3: printf("DA converter error! Code3:Setting is incorrect.\n");
			break;
	}
	return 0;
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//ADコンバータエラーチェック関数
//aderrchk(int adcerr)
//引数1:adcerr adのエラー
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
int aderrchk(int adcerr){
	switch(adcerr){
		case 1: printf("DA converter error! Code1:Is not open.\n");
			break;
		case 2: printf("DA converter error! Code2:No drivers are installed correctly.\n");
			break;
		case 4: printf("DA converter error! Code4:Too many connections number.\n");
			break;
		case 5: printf("DA converter error! Code5:Could not open the device.\n");
			break;
		case 6: printf("DA converter error! Code6:Can not find the specified device.\n");
			break;
		case 7: printf("DA converter error! Code7:The specified device is not opened.\n");
			break;
		case 8: printf("DA converter error! Code8:Error of the specified parameter.\n");
			break;
		case 9: printf("DA converter error! Code9:Communication error USB.\n");
			break;
		case 10: printf("DA converter error! Code10:Unable to allocate memory.\n");
			break;
		case 11: printf("DA converter error! Code11:Continuous runnig capture.\n");
			break;
		case 12: printf("DA converter error! Code12:Data acquisition is not continuous.\n");
			break;
		case 13: printf("DA converter error! Code13:Continuous uptake has not been started.\n");
			break;
		case 14: printf("DA converter error! Code14:Memory overflow.\n");
			break;
		case 15: printf("DA converter error! Code15:The first column of data error.\n");
			break;
		case 99: printf("DA converter error! Code99:Other error.\n");
			break;
	}
	return 0;
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//shutdown関数
//shutdown()
//
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
int shutdown(){
	switch(type){
		case 0:
			//sin
			//Tusbdam_Single_Out(daid, channel, 2048);
			break;
		case 1:
			//step
			//Tusbdam_Single_Out(daid, channel,0);
			break;
	}
	return 0;
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//設定関数
//settings(daid, adid)
//引数1:daid DAコンバータのID
//引数2:adid ADコンバータのID
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
int settings(int daid, int adid){
	int err = 0;
	//int type = 0;
	int dacerr = 0;
	int adcerr = 0;
	//出力波形設定
	printf("What is output type?(0=sin,1=step):");
	scanf("%d", &type);
	while(1){
		if(type == 0){
			printf("Output type:sin\n");
			break;
		}else if(type == 1){
			printf("Output type:step\n");
			break;
		}else{
			printf("Error!\nWhat is output type?(0=sin,1=step):");
			scanf("%d", &type);
		}
	}
	//チャンネル設定
	printf("DA converter output channels?(1 or 2):");
	scanf("%d", &channel);
	while(1){
		if(channel == 1){
			break;
		}else if(channel == 2){
			break;
		}else{
			printf("Error!\nDA converter output channels?(1 or 2):");
			scanf("%d", &channel);
		}
	}
	printf("channel:%d\n", channel);
	//電圧設定
	if(type == 1){
		//step
		printf("How much voltage?(0-5[V]):");
		scanf("%lf", &voltage);
		while(voltage > 5){
			printf("Error!\nHow much voltage?(0-5[V]):");
			scanf("%lf", &voltage);
		}
		printf("%lf[V]\n", voltage);
	}else if(type == 0){
		//sin
		printf("How much voltage?(0-2.5[V]):");
		scanf("%lf", &voltage);
		while(voltage > 2.5){
			printf("Error!\nHow much voltage?(0-2.5[V]):");
			scanf("%lf", &voltage);
		}
		printf("%lf[V]\n", voltage);
	}else{
		err=1;
	}
	//実行時間設定
	printf("How much run time?(0-100[s]):");
	scanf("%d", &time);
	while(1){
		if(time > 0){
			if(time < 100){
				break;
			}else{
				printf("Error!\nHow much run time?(0-100[s])");
				scanf("%d", &time);
			}
		}else{
			printf("Error!\nHow much run time?(0-100[s])");
			scanf("%d", &time);
		}
	}
	printf("%d[s]\n", time);
	//比例ゲイン設定
	printf("How much proportional gain(Kp)?:");
	scanf("%lf", &Kp);
	printf("%lf\n", Kp);
	//積分時間設定
	printf("How much integration time(Ti)?:");
	scanf("%lf", &Ti);
	printf("%lf\n", Ti);

	/*//ADクロック設定
	adcerr = Tusbadmh_Clock_Select(adid, 0, 49, 8);
	//DAクロック設定
	dacerr = Tusbdam_Clock_Set(daid, 1, 2);
	//DAデータの出力回数
	dacerr = Tusbdam_Cycle_Set(daid, 10);
	//ADの入力タイプ
	switch(channel){
		case 1:{
			adcerr = Tusbadmh_InputType(daid, type, 0);
			break;
		}
		case 2:{
			adcerr = Tusbadmh_InputType(daid, 0, type);
			break;
		}
		default :{
		err = 1;
		break;
		}
	}*/
	if(err == 1){
		//エラー
		printf("Error!:Some errors were detected.\n");
		return 1;
	}else if(err == 0){
		return 0;
	}
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//ADコンバータオープン関数
//adopen(int adid)
//引数1:adid ADコンバータのID
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
int adopen(int adid){
	int adcerr = 0;
	//printf("What is the ID of the AD converter?(0-15):");
	//scanf("%d", &adid);
	printf("AD converter ID is %d.It is open to the AD converter...", adid);
	//Tusbadmh_Load();
	//adcerr = Tusbadmh_Chk(daid);
	if(adcerr == 0){
	//ループを抜ける
	printf("Can be used.\n");
	return 0;
	}else{
	//エラー
	aderrchk(adcerr);
	return 1;
	}
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//DAコンバータオープン関数
//daopen(int daid)
//引数1:daid DAコンバータのID
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
int daopen(int daid){
	int dacerr = 0;
	//printf("What is the ID of the DA converter?(0-15):");
	//scanf("%d", &daid);
	printf("DA converter ID is %d.It is open to the DA converter...", daid);
	//dacerr = Tusbdam_Device_Open(daid);
	if(dacerr == 0){
	printf("Can be used.\n");
	return 0;
	}else{
		//エラー
		daerrchk(dacerr);
		return 1;
	}
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//波形生成関数
//sin(int fcnt)
//引数1:fcnt 正弦波分割数
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
int sin_set(int fcnt){
	int data[10];
	int i = 0;
	//int dacerr = 0;
	for(i = 0 ; i < 10; i++){
		data[i] = 2048 * (voltage / 2.5) * sin(2 * 3.14159265 * (i+10 * fcnt) / 1700) + 2048; //+ 2048 * (voltage1/2.5);
		if(data[i] > 4095){
			data[i] = 4095;
		}else if(data[i] < 0){
			data[i] = 0;
		}
	}
	//dacerr = Tusbdam_Set_Memory(daid, channel, 10, data[i]);
		return 0;
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//フィードバック関数
//feedback()
//
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
int feedback(){
	//D1:目標値
	//D2:変位センサからの出力
	double D1, D2 = 0;
	int data[1048576];
	int leng = 1048576;
	int err = 0;
	/*if(Tusbadmh_Data_Get(daid, 0, data[1], leng) != 0){
		err = 1;
		printf("Failed to execute the function DLL.Close the device.\n");
		Tusbadmh_Unload();
	}
	if(leng <> 0){
		D1 = 2.5 * Sin(2 * 3.141592 * (10 + 10 * fcnt) / 1700);
		D2 = ((data[leng] - 32768) / 32768) - initvolt;
		//フィードバック
		volt = D1 - D2;
		if(volt > 2.5){
			volt = 2.5
		}
	}else{
		cerr = cerr + 1;
	}*/
	if(err == 1){
		return 1;
	}else if(err == 0){
		return 0;
	}
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//出力関数
//output()
//
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
int output(){
	int err = 0;
	//int dacerr = 0;
	//int adcerr = 0;
	switch(type){
		case 0:{
			//sin
			//da内部クロック,2MHz(最高)
			/*dacerr = Tusbdam_Clock_Set(daid, 1, 2);
			if(dacerr != 0){
				//エラー
				daerrchk(dacerr);
				err = 1;
				printf("Some errors were detected.\n");
				//終了処理
				Tusbadmh_Unload();
				Tusbdam_Device_Close(daid);
				break;
			}
			fcnt = 0;
			//daデータ数と同じにする
			dacerr = Tusbdam_Cycle_Set(daid, 10);
			if(dacerr != 0){
				//エラー
				dacerrchk(dacerr);
				err = 1;
				printf("Some errors were detected.\n");
				Tusbadmh_Unload();
				Tusbdam_Device_Close(daid);
				break;
			}
			adcerr = Tusbadmh_InputType(daid, 0, 0);
			if(adcerr != 0){
				adcerrchk(adcerr);
				err = 1;
				printf("Some errors were detedted.\n");
				Tusbadmh_Unload();
				Tusbdam_Device_Close(daid);
				break;
			}
			//実行開始
			printf("start the run...\n");
			adcerr = Tusbadmh_Adc_Start(daid, 100000, 0, 3, 0, 0);
			if(adcerr != 0){
				//エラー
				adcerrchk(adcerr);
				err = 1;
				printf("Some errors were detected.\n");
				Tusbadmh_Unload();
				Tusbdam_Device_Close(daid);
				break;
			}
			//ソフトウェアトリガ
			adcerr = Tusbadmh_Trigger(adid);
			if(adcerr != 0){
				adcerrchk(adcerr);
				err = 1;
				printf("Some errors were detected.\n");
				Tusbadmh_Unload();
				Tusbdam_Device_Close(daid);
				break;
			}
			//初期電圧を測定する
			//10msの遅延
			int data[1048576];
			int leng = 1048576;
			if(Tusbadmh_Data_Get(daid, 0, data[1], leng) != 0){
				//エラー
				printf("Some errors were detected.\n");
				Tusbadmh_Unload();
				err = 1;
			}
			initvolt = ((data[leng] - 32768)/32768)/kouseikeisu;
			*/
				   //count:1[s]カウンタ
			int count = 0;
			MMRESULT timerID1 = timeSetEvent(1000,									// 間隔[ms]
											0,										// 分解能
											timerProc,								// 割り込み関数
											(DWORD)&count,							// ユーザーパラメータ
											TIME_PERIODIC | TIME_CALLBACK_FUNCTION	// 動作フラグ
											);
			if( !timerID1 ){
				printf("Failed to register a timer.\n");
				return -2;
			}
			MMRESULT timerID2 = timeSetEvent(12,									// 間隔[ms]
											0,										// 分解能
											timerFeedback,								// 割り込み関数
											(DWORD)&count,							// ユーザーパラメータ
											TIME_PERIODIC | TIME_CALLBACK_FUNCTION	// 動作フラグ
											);
			if(!timerID2){
				printf("Failed to register a timer.\n");
				return -2;
			}
			while(count < time){
				//実行中のループ
				printf("%d ",count);
			}
			// タイマー割り込み関数の登録抹消
			timeKillEvent(timerID1);
			timeKillEvent(timerID2);
			
			break;
		}
		case 1:{
			//step
			/*outputdata = 2048 * voltage / 2.5 + 2047;
			dacerr = Tusbdam_Single_Out(daid, channel, outputdata);
			if(dacerr != 0){
				daerrchk(dacerr);
				err = 1;
				printf("Some errors were detected.\n");
				//終了処理

				break;
				}
			while(1){
				if(flag == 1){
					break;
				}
			}
			*/
			break;
		}
	}
	if(err == 1){
		return 1;
	}else{
		return 0;
	}
}

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//main関数
//main()
//
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
int main(int argc, char *argv[]){
	int err = 0;
	int daid = 0;
	int adid = 0;
	char cmd;
	int fcnt = 0;
	int i = 0;	//forのための変数
	//画面のクリア
	system("cls");
	printf("Control program for the linear guide. Version 0.1\n");
	printf("Please press key one of the following key.(s:start,e:exit,c:clear)");
	//メインメニュー
	while(1){
		//cmd = getchar();
		scanf("%c", &cmd);
		switch(cmd){
			case 's':{
				printf("Prepare for execution...\n");
				//adコンバータオープン
				printf("What is the ID of the AD converter?(0-15):");
				scanf("%d", &adid);
				if(adopen(adid) == 1){
					err = 1;
					printf("An error was detected in adopen(). Will cease...\n");
					//exit();
					break;
				}
				//daコンバータオープン
				printf("What is the ID of the DA converter?(0-15):");
				scanf("%d", &daid);
				if(daopen(daid) == 1){
					err = 1;
					printf("An error was detected in daopen(). Will cease...\n");
					//exit();
					break;
				}
				if(settings(daid, adid) == 1){
					err = 1;
					printf("An error was detected in settings(). Will cease...\n");
					//exit();
					break;
				}
				//出力開始
				if(output()==1){
					err=1;
					printf("An error was detected in output(). Will cease...|n");
					break;
				}
				//出力終了
				printf("Please press key one of the following key.(s:start,e:exit,c:clear)");
				scanf("%c", &cmd);
				break;
			}
			case 'e':{
				printf("Exit...\n");
				return 0;
			}
			case 'c':{
				//画面のクリア
				system("cls");
				printf("Please press key one of the following key.(s:start,e:exit,c:clear)");
				scanf("%c", &cmd);
				break;
			}
			//想定外の文字をタイプした場合
			default :{
				printf("Invaild Input\nPlease press key one of the following key.(s:start,e:exit,c:clear)");
				scanf("%c", &cmd);
				break;
			}
		}
	}
	//エラー
	return 1;
}