//=================================================================== // AXP-AD02 連続サンプリング例 //------------------------------------------------------------------- // Copyright (c) ADTEK SYSTEM SCIENCE Co.,Ltd. // // このプログラムは AXP-AD02 で連続サンプリングを行うサンプルです。 // なお、AXP-AD02から読み込んだデータはプログラムの簡素化のために読み // 捨てしておりますので、予めご了承ください。 // また、このプログラムを実行しても空のダイアログが表示されるだけです // ので、その点も予めご了承ください。 // // 動作は、AXP-AD02に連続サンプリングを実行させ、タイマを使い定期的に // データの取り込みを行っております。定期的にデータ取り込みを行うこと // によって、ドライバのサンプリングバッファが溢れることを防ぎ、連続し // たサンプリングを可能にしております。 // // コンパイル方法 MS-Visual C++ : // プロジェクトを新規に作成し、当ファイル(Sample.c)とAxpad02w.cを追加 // してコンパイルを行ってください。 //=================================================================== #include #include #include "Axpad02w.h" // タイマーID #define SMP_TIMERID 100 // メッセージ #define SMP_MSGBASE WM_USER + 100 #define SMP_CARD_REMOVAL SMP_MSGBASE + AD02_WM_OFS_CARD_REMOVAL #define SMP_EOC SMP_MSGBASE + AD02_WM_OFS_EOC #define SMP_HALF_FULL SMP_MSGBASE + AD02_WM_OFS_HALF_FULL #define SMP_OVERFLOW SMP_MSGBASE + AD02_WM_OFS_OVERFLOW #define SMP_OVERRUN SMP_MSGBASE + AD02_WM_OFS_OVERRUN #define SMP_EXIN SMP_MSGBASE + AD02_WM_OFS_EXIN // データ取得バッファサイズ #define DATA_BUFSIZE 300 // マクロ #define HALT(x) SendMessage(x,WM_CLOSE,0,0) //------------------------------------------------------------------- // 関数プロトタイプ //------------------------------------------------------------------- LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); VOID ErrorProc( HWND hWnd,WORD wLogSocket ); //------------------------------------------------------------------- // グローバル変数 //------------------------------------------------------------------- char szClassNme[] = "AXP-AD02 Sample program"; WORD wLogSocket; AD02MODE mode; // 動作モード PWORD pwBuffer = NULL; // データ取得バッファ DWORD dwStatus,dwNumData; // ステータス・データ数 //=================================================================== // メイン //=================================================================== int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow) { HWND hWnd; MSG msg; WNDCLASS wc; //--------------------------------------------------------------- // ウインドウクラスの登録 //--------------------------------------------------------------- if (!hPreInst) { wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = szClassNme; if (!RegisterClass(&wc)) return FALSE; } //--------------------------------------------------------------- // ウインドウ作成 //--------------------------------------------------------------- hWnd = CreateWindow( szClassNme, "AXP-AD02 Sample", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); //--------------------------------------------------------------- // メッセージループ //--------------------------------------------------------------- while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (msg.wParam); } //=================================================================== // ウインドウメッセージの処理 //=================================================================== LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch (msg) { //----------------------------------------------------------- // ウインドウ作成時の処理 //----------------------------------------------------------- case WM_CREATE: //------------------------------------------------------- // データ取得用バッファの準備 //------------------------------------------------------- pwBuffer = (PWORD)malloc( DATA_BUFSIZE * sizeof(WORD) ); if ( pwBuffer == NULL ) { MessageBox( hWnd, "メモリアロケートエラー", "Sample", (MB_OK|MB_ICONSTOP) ); HALT( hWnd ); } //------------------------------------------------------- // AXP-AD02 制御用DLLを開く //------------------------------------------------------- if ( FALSE == Ad02wDllOpen() ) { ErrorProc( hWnd, AD02_SOCKET_AUTO ); HALT( hWnd ); } //------------------------------------------------------- // デバイスを開く // ここでウインドウハンドルとメッセージベースを指定するこ // とによって、ドライバからのメッセージを受信できるように // なります //------------------------------------------------------- wLogSocket = AD02_SOCKET_AUTO; if ( FALSE == Ad02wCreate( &wLogSocket, hWnd, SMP_MSGBASE, NULL ) ) { ErrorProc( hWnd, AD02_SOCKET_AUTO ); HALT( hWnd ); } //------------------------------------------------------- // サンプリングモード設定 // // バッファサイズ = 2000ワード // サンプリング開始チャンネル = 0 // サンプリング最終チャンネル = 0 // サンプリングモード = 連続 // タイマ値 = 1msec // トリガソース = 内部 // 電圧レンジ = ±10volt //------------------------------------------------------- mode.cwBuffer = 2000; mode.dwChFirst = 0; mode.dwChLast = 0; mode.dwSampleMode = AD02_SM_CONTINUOUS; mode.dwTimer = 100; mode.dwTrigSource = AD02_TS_INTERNAL; mode.dwVoltageRange = AD02_VR_S10V; if ( FALSE == Ad02wSetMode( wLogSocket, &mode ) ) { ErrorProc( hWnd, wLogSocket ); HALT( hWnd ); } //------------------------------------------------------- // サンプリング開始 //------------------------------------------------------- if ( FALSE == Ad02wStartSampling( wLogSocket ) ) { ErrorProc( hWnd, wLogSocket ); HALT( hWnd ); } //------------------------------------------------------- // ユーザタイマ起動 //------------------------------------------------------- if ( SetTimer( hWnd, SMP_TIMERID, 100, NULL ) == 0 ) { MessageBox( hWnd, "タイマー失敗", "Sample", (MB_OK|MB_ICONSTOP) ); } break; //----------------------------------------------------------- // タイマメッセージ(約100mSec毎に発生) //----------------------------------------------------------- case WM_TIMER: //------------------------------------------------------- // サンプリングステータス取得 //------------------------------------------------------- if ( FALSE == Ad02wGetSamplingStatus( wLogSocket, &dwNumData, &dwStatus ) ) { // ステータス取得エラー break; } if ( dwNumData > 0 ) { //--------------------------------------------------- // サンプリングデータ取り込み //--------------------------------------------------- if ( dwNumData >= DATA_BUFSIZE ) dwNumData = DATA_BUFSIZE; if ( FALSE == Ad02wGetData( wLogSocket, pwBuffer, dwNumData ) ) { // データ取得エラー break; } //--------------------------------------------------- // TODO: ここにデータ取得後の処理を書きます //--------------------------------------------------- } break; //----------------------------------------------------------- // カード抜去メッセージ //----------------------------------------------------------- case SMP_CARD_REMOVAL: //------------------------------------------------------- // MEMO: ここに異常終了処理を記述します // //------------------------------------------------------- MessageBox( hWnd, "アプリケーション実行中にカードを抜かないで下さい", "Sample", (MB_OK|MB_ICONSTOP) ); HALT( hWnd ); break; //----------------------------------------------------------- // サンプリング終了メッセージ(非連続サンプリング用) //----------------------------------------------------------- case SMP_EOC: //------------------------------------------------------- // MEMO: ここにサンプリング終了時の処理を記述します // このサンプルでは使用しません //------------------------------------------------------- MessageBox( hWnd, "サンプリング終了", "Sample", (MB_OK|MB_ICONSTOP) ); break; //----------------------------------------------------------- // バッファハーフフルメッセージ //----------------------------------------------------------- case SMP_HALF_FULL: //------------------------------------------------------- // MEMO: ここでハーフフル処理を記述します、このサンプルでは特 // に使用しませんが、このタイミングでデータを取得するこ // とも可能です //------------------------------------------------------- MessageBox( hWnd, "バッファハーフフル", "Sample", (MB_OK|MB_ICONSTOP) ); break; //----------------------------------------------------------- // バッファオーバーフローメッセージ //----------------------------------------------------------- case SMP_OVERFLOW: //------------------------------------------------------- // MEMO: ドライババッファが溢れた時の処理を記述します、サンプ // リングを継続する場合は一度サンプリングを停止しサンプ // リングモード設定後にサンプリングスタートしてください //------------------------------------------------------- MessageBox( hWnd, "バッファオーバーフローが発生しました", "Sample", (MB_OK|MB_ICONSTOP) ); HALT( hWnd ); break; //----------------------------------------------------------- // バッファオーバーランメッセージ //----------------------------------------------------------- case SMP_OVERRUN: //------------------------------------------------------- // MEMO: デバイスバッファが溢れた時の処理を記述します、サンプ // リングを継続する場合は一度サンプリングを停止しサンプ // リングモード設定後にサンプリングスタートしてください //------------------------------------------------------- MessageBox( hWnd, "バッファオーバーランが発生しました", "Sample", (MB_OK|MB_ICONSTOP) ); HALT( hWnd ); break; //----------------------------------------------------------- // 外部入力割り込みメッセージ //----------------------------------------------------------- case SMP_EXIN: //------------------------------------------------------- // MEMO: ここに汎用入力への割り込みが発生した時の処理を記述し // てください。 //------------------------------------------------------- MessageBox( hWnd, "外部入力割り込みが発生しました", "Sample", (MB_OK|MB_ICONSTOP) ); HALT( hWnd ); break; //----------------------------------------------------------- // ウインドウ破棄時の処理 //----------------------------------------------------------- case WM_DESTROY: //------------------------------------------------------- // ユーザタイマ破棄 //------------------------------------------------------- KillTimer(hWnd,SMP_TIMERID); //------------------------------------------------------- // サンプリング停止 //------------------------------------------------------- Ad02wStopSampling( wLogSocket ); //------------------------------------------------------- // デバイス解放 //------------------------------------------------------- Ad02wClose( wLogSocket ); //------------------------------------------------------- // AXP-AD02 制御用DLLを閉じる //------------------------------------------------------- Ad02wDllClose(); //------------------------------------------------------- // データ取得バッファ解放 //------------------------------------------------------- if ( pwBuffer != NULL ) free( pwBuffer ); PostQuitMessage(0); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); } //=================================================================== // エラー処理 //=================================================================== VOID ErrorProc( HWND hWnd, WORD wLogSocket ) { DWORD dwErr = Ad02wGetLastError( wLogSocket ); TCHAR szBuf[256]; switch( dwErr ) { case AD02_SUCCESS: wsprintf( szBuf,"異常なし(正常終了)" ); break; case AD02_ERR_SYSTEM: wsprintf( szBuf,"正常にドライバがロードされていない可能性があります" ); break; case AD02_ERR_NO_DEVICE: wsprintf( szBuf,"使用可能なデバイスがありません" ); break; case AD02_ERR_NOT_CREATED: wsprintf( szBuf,"指定のデバイスは使用宣言されていません" ); break; case AD02_ERR_IN_USE: wsprintf( szBuf,"指定のデバイスは他のプロセスで使用中です" ); break; case AD02_ERR_INVALID_SOCKET: wsprintf( szBuf,"無効な論理ソケット番号です" ); break; case AD02_ERR_RESOURCE: wsprintf( szBuf,"リソースエラー" ); break; case AD02_ERR_INVALID_ARGUMENT: wsprintf( szBuf,"不正な引数を指定しました" ); break; case AD02_ERR_VOLTAGE_RANGE: wsprintf( szBuf,"不正な電圧値を指定しました" ); break; case AD02_ERR_CHANNEL: wsprintf( szBuf,"不正なチャンネルを指定しました" ); break; case AD02_ERR_TIMER: wsprintf( szBuf,"不正なタイマを指定しました" ); break; case AD02_ERR_TRIG_SOURCE: wsprintf( szBuf,"不正なトリガを指定しました" ); break; case AD02_ERR_SAMPLE_MODE: wsprintf( szBuf,"不正なモードを指定しました" ); break; case AD02_ERR_NOT_ENOUGH_MEM: wsprintf( szBuf,"指定されたバッファを確保できませんでした" ); break; case AD02_ERR_NO_DATA: wsprintf( szBuf,"データが要求数分ありません" ); break; case AD02_ERR_NO_DLL: wsprintf( szBuf,"DLLが正常にロードされませんでした" ); break; case AD02_ERR_NO_SETMODE: wsprintf( szBuf,"モードが設定されていませんでした" ); break; case AD02_ERR_BUSY: wsprintf( szBuf,"サンプリング動作中です" ); break; case AD02_ERR_WRAPDLL: wsprintf( szBuf, "DLLが正常にオープンできませんでした"); break; default: wsprintf( szBuf,"未知のエラー" ); break; } MessageBox( hWnd, szBuf, "Sample", (MB_OK|MB_ICONSTOP) ); }