- 締切済み
ADボードでリアルタイムサンプリング
プログラムはこちらです #define NUM 20000 void CAdDrawGraphDlg::OnFileout() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください int nRet; int i = 0, j = 0, file_count = 0; char fname[32]; HANDLE hDeviceHandle; ADSMPLREQ SmplConfig; ADBOARDSPEC BoardSpec; WORD wSmplData; FILE *fp = NULL; ULONG ulSmplNum = NUM; /* デバイスのオープン */ if((hDeviceHandle = AdOpen("FBIAD1")) == INVALID_HANDLE_VALUE){ AfxMessageBox("デバイスのオープンに失敗しました",MB_OK, 0); return; } nRet = AdGetSamplingConfig(hDeviceHandle,&SmplConfig); if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("サンプリング設定情報の読み出しに失敗しました",MB_OK, 0); } nRet = AdGetDeviceInfo(hDeviceHandle, &BoardSpec); if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("デバイスの情報取得にに失敗しました", MB_OK, 0); } while(1){ /* 無限ループ */ /*時間の取得*/ int H,M,S; /* config初期化 */ SmplConfig.SmplChReq[0].ulChNo = 2; // SmplConfig.ulSmplNum = NUM * i; //SmplConfig.ulTrigMode = AD_ETERNITY; SmplConfig.fSmplFreq = 20000; SmplConfig.SmplChReq[0].ulRange = AD_5V; nRet = AdSetSamplingConfig(hDeviceHandle, &SmplConfig); if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("サンプリング条件設定に失敗しました",MB_OK, 0); } nRet = AdStartSampling(hDeviceHandle, FLAG_SYNC); /* 書き込みファイルのオープン */ sprintf(fname, "DATA.%d.csv", file_count); fp = NULL; if((fp = fopen(fname, "w")) == NULL){ /* error */ return; } setbuf(fp, NULL); /* ライブラリ内バッファリングを無効にする */ for(i = 0;; i++){ SmplConfig.ulSmplNum = NUM * i; wSmplData = 0; /* NUM回データを取得 */ for(j = 0; j < NUM; j++){ ulSmplNum = 1; double val; if(AdGetSamplingData(hDeviceHandle, &wSmplData, &ulSmplNum) != AD_ERROR_SUCCESS){ val = wSmplData; val = ((val * 10) / 4096) - 5; fprintf(fp, "%d, %f\n", i * NUM + j, val); //fprintf(fp, "[%d], %d, %d\n", ulSmplNum, i * NUM + j, wSmplData); } else{ val = wSmplData; val = ((val * 10) / 4096) - 5; CTime theTime=CTime::GetCurrentTime(); // mm=theTime.GetMonth(); // dd=theTime.GetDay(); H =theTime.GetHour(); M =theTime.GetMinute(); S =theTime.GetSecond(); fprintf(fp, "%d,%d:%d:%d, %f\n", i * NUM + j,H,M,S, val); //fprintf(fp, "%d, %d, %d\n", ulSmplNum, i * NUM + j, wSmplData); } } if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("CSVファイル作成に失敗しました", MB_OK, 0); } } /* end of for */ fclose(fp); file_count++; } /* end of while */ /* デバイスのクローズ */ nRet = AdClose(hDeviceHandle); if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("デバイスのクローズに失敗しました"); } fclose(fp); } 問題は20000点で1秒時刻が進むはずですが2000点で1秒時計が進んでしまいます。 時刻以外は正常で、1周期1sの波形を入力したときはそのしっかり20000点存在するので1秒間に 20000点でサンプリングしています。 解決策があれば教えてください。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- hidebun
- ベストアンサー率50% (92/181)
> バッファを使わないでその保証をするのは、不可能ではないでしょうか。 失礼。バッファを使わないで、データ取りこぼし無しを保証するのは、不可能ではないでしょうか。
- hidebun
- ベストアンサー率50% (92/181)
> 1周期1sの波形を入力したときはそのしっかり20000点存在するので1秒間に20000点でサンプリングしています。 なんだか妙な日本語で、ちょっと確認してみたいんですが、 1.20000点のデータを選んでグラフ化してみると、きれいに1周期分のデータが表示されるのですか? 2.20000Hzでサンプリングをするのは、ADボードの方ですが、プログラムはそれよりも速い間隔でADボードにアクセスする保証はないように思います。バッファを使わないでその保証をするのは、不可能ではないでしょうか。 3.20000Hzより速い間隔で、ADボードにアクセスできている場合、ADボードのバッファが空で、データを取り出すことができない状況になると思います(AD_ERROR_GET_DATAが返る)。その時は、!= AD_ERROR_SUCCESSのブロックに入ると思いますが、頻繁にそのブロックに入っていますか?入っていなければ、プログラムがADボードにアクセスする間隔が20000Hzを下回っていると思います。