• ベストアンサー

ADボードプログラムC++

ADボードでデータをCSVで取り出しているのですが、サンプリングレートとサンプリング件数が決まっているので、長い時間データをとり続けることができません。 どうしたら自分がプログラムを閉じるまで永遠にデータを出力し続けることができますか? 教えてください

質問者が選んだベストアンサー

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.2

> どうしてもサンプリング件数を設定しないといけません それは、あなたがAdStartFileSampling()関数を使って、ファイルに落とそうとしている から、発生している制約です。 http://www.interface.co.jp/catalog/prdchelp/japanese/gpc3100/AdStartFileSampling.htm によると、この関数は、 >本関数は連続サンプリングが終了するまでアプリケーションに処理が戻りません ということなので、あらかじめサンプル数を指定してやらないと、 「いつ関数を終えれば良いのか」「いつファイルに書き込んだら良いのか」が、 わからず、やむなくサンプル数を必須指定する仕様になっているのでしょう。 あなたの要求にぴったりのヘルプが以下かと思います。 http://www.interface.co.jp/catalog/prdchelp/japanese/gpc3100/SamplingReference.htm#1 AdGetSamplingData()関数を使って、自前のバッファにデータを取得し、 第3引数に取得されたバイト数を元に、ファイルに書き込む。 >本関数ではサンプリングバッファからデータを取得したら、取得したデータはサンプリングバッファ内からクリアされます。 ADボードは、わずかなバッファを持っているはずですよ。 取得したデータはバッファからクリアされるので、取得したものをどんどん ファイルに書いていけば良いです。 プログラミングの難易度としてはそれほど高くないと思います。 ぜひトライしてみて下さい。

masasugi0518
質問者

お礼

わざわざ私のためにご丁寧にしてくださり、ありがとうございます。 とりあえずADGetsamplingData関数でやってみます

その他の回答 (1)

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.1

今のプログラムは、受信データを即ファイルに書いているわけではないんですか? どういう構造で、サンプリングレートとサンプル数の制約ができてしまっているのでしょう。 リアルタイムにデータ処理をする必要がないのであれば、受信→ファイル書き込みを 延々と行なっていけば、長時間のデータ保存ができると思います。 ただし、32bit版のWindows等では、ファイルサイズ4Gの壁があるので、 ファイルサイズが一定サイズ以上になったら、別のファイルに続きを 書きこむようなスイッチ機構を考慮しなければなりませんが。 リアルタイムにデータ処理をする必要があるということであれば、技術的な敷居がかなり高くなります。 まずは、実現したい要求を明確に示して下さい。

masasugi0518
質問者

補足

私の使用しているADボードはバッファ機能のないADボードです。雷の観測に使用するため、リアルタイムにどんどんデータを記録していくプログラムを作成しています。 int nRet; HANDLE hDeviceHandle; ADSMPLREQ SmplConfig; ADBOARDSPEC BoardSpec; hDeviceHandle = AdOpen ("FBIAD1"); if (hDeviceHandle == INVALID_HANDLE_VALUE){ AfxMessageBox("デバイスのオープンに失敗しました",MB_OK, 0); return; } else{ 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); } SmplConfig.SmplChReq[0]. ulChNo = 2; SmplConfig.ulSmplNum = 20000; SmplConfig.fSmplFreq = 20000; SmplConfig.SmplChReq[0]. ulRange = AD_5V; nRet = AdSetSamplingConfig(hDeviceHandle,&SmplConfig ); if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("サンプリング条件設定に失敗しました",MB_OK, 0); } nRet = AdStartFileSampling(hDeviceHandle, "DATA .csv",FLAG_CSV); if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("CSVファイル作成に失敗しました", MB_OK, 0); } } } nRet = AdClose(hDeviceHandle); if (nRet != AD_ERROR_SUCCESS){ AfxMessageBox("デバイスのクローズに失敗しました"); } どうしてもサンプリング件数を設定しないといけません。設定しないとサンプリング件数が1024点になります。とりあえずサンプリングレートは2万のままでやりたいです。ADボードの使用でサンプリング件数は1.000.000点までしか入力できないので、1.000.000(件数)/20.000(サンプリングレート)で50秒しか記録できません。 常にリアルタイムで記録し続けるプログラムを教えてください。

関連するQ&A

  • ADボードのプログラムでの無限サンプリング

    自分でプログラムをADsamplingData関数でやってみたのですがデータが指定の保存場所に出力されません。 CSV形式で保存するプログラムを作ったつもりです。 保存場所はEドライブのEdataの中に出力されるようにしたいです。 ちなみにプログラムはこちらです。 int nRet; HANDLE hDeviceHandle; ADSMPLREQ SmplConfig; ADBOARDSPEC BoardSpec; ULONG ulSmplNum; FILE *outp; WORD wSmplData[20000][2]; hDeviceHandle = AdOpen ("FBIAD1"); if (hDeviceHandle == INVALID_HANDLE_VALUE){ AfxMessageBox("デバイスのオープンに失敗しました",MB_OK, 0); return; } else{ 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); } { SmplConfig.SmplChReq[0]. ulChNo = 2; SmplConfig.ulSmplNum = 20000; 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); if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("CSVファイル作成に失敗しました", MB_OK, 0); } AdGetSamplingData(hDeviceHandle,&wSmplData[0][0], &ulSmplNum ); outp = fopen("E\\Edata\\record.csv","a"); fprintf(outp,"%f\n",wSmplData); fclose(outp); } } } 何が違うのですか? dビルドはできるのですが、プログラムを動かしてもファイルができません。

  • ADボードにとるCSVでの無限サンプリング

    ADボードで無限サンプリングをおこないたいのですが。 作成したCSVファイルにデータが1行しか作成されません。 何が問題でしょうか? ちなみにプログラムはこちらです。 int nRet; HANDLE hDeviceHandle; ADSMPLREQ SmplConfig; ADBOARDSPEC BoardSpec; ULONG ulSmplNum; FILE *outp; WORD wSmplData[20000][2]; hDeviceHandle = AdOpen ("FBIAD1"); if (hDeviceHandle == INVALID_HANDLE_VALUE){ AfxMessageBox("デバイスのオープンに失敗しました",MB_OK, 0); return; } else{ 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); } { SmplConfig.SmplChReq[0]. ulChNo = 2; SmplConfig.ulSmplNum = 20000; 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); if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("CSVファイル作成に失敗しました", MB_OK, 0); }*/ /* nRet = AdStartFileSampling( hDeviceHandle, "DATA.CSV", FLAG_CSV ); if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("CSV ファイル作成に失敗しました", MB_OK, 0); }*/ AdGetSamplingData(hDeviceHandle,&wSmplData[0][0], &ulSmplNum ); AdOutputDO(hDeviceHandle,1); outp = fopen("E:\\Edata\\record.csv","a"); fprintf(outp,"%f\n",wSmplData[0][0]); fclose(outp); // 終了処理. nRet = AdClose( hDeviceHandle ); if (nRet != AD_ERROR_SUCCESS) { AfxMessageBox("デバイスのクローズに失敗しました"); } } } }

  • 高速なサンプリングが可能なAD/DAカード(ボード)を探しています

    大学で研究をしている者です.ハードウェアに関してはほぼ素人です. 実験でAD/DAを行うため,以下のようなAD/DAカード(ボード)を探しています. ・ADは(最低でも)50[kHz]以上のサンプリングが可能 ・DAは10[kHz]程度の出力が可能 調べてみても専門用語が多く,高い買い物になりそうなので,使ってみて失敗したくありません. ですので,ノウハウを知っている方がいらっしゃいましたら御助言よろしくお願いします. 実験はC++を使ってセンサに電圧を出力し,センサからADで得られた波形をリアルタイムに解析するといった内容です. ノートPCを使う予定なのでAD/DAカードと記述しましたが,ボードでもかまいません.(カードよりもボードの方が一般的に性能が良いようなことがあればボードを使うつもりです.) 既出でしたら申し訳ありません.

  • AD/DAボードを用いたAD/DA変換プログラムについて

    C++を用いてAD/DAボードを用いたAD/DA変換プログラムを作成しようと思うのですが、何から書けばいいのか分かりません。 ボードの会社のHPにプログラミングの方法が記載されていたのですが、現在使用している開発環境よりも古いので、あまり参考に出来ませんでした。 調べたりもしたのですが、参考に出来るものがありませんでした。 環境は、  OS : WindowsXP  C++ : Visual C++ 2005 Express Edition  AD/DAボード : Interface製 PCI-3521 です。 参考になりそうなHP、本等がありましたら教えてください。 よろしくお願いします。

  • ADボードのデータの遅れについて

    ADボードからデータを取得し、ファイルに書き出す下記のようなプログラムを作成中です。 データがNUMを境に遅れているという現象が発生しております。 #define NUM 20000 void CAdDrawGraphDlg::OnFileout() { // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください int nRet; int i = 0, j = 0; HANDLE hDeviceHandle; ADSMPLREQ SmplConfig; ADBOARDSPEC BoardSpec; WORD wSmplData[NUM]; FILE *fp = NULL; ULONG ulSmplNum = NUM; if((fp = fopen("DATA.csv", "w")) == NULL){ /* error */ return; } //setbuf(fp, NULL); /* デバイスのオープン */ 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); } /* config初期化 */ SmplConfig.SmplChReq[0].ulChNo = 2; SmplConfig.ulSmplNum = NUM; //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); //for(;;i++){ /* 無限ループ */ for(i = 0; i < 4; i++){ /* NUM回データを取得 */ for(j = 0; j < NUM; j++){ double val; AdGetSamplingData(hDeviceHandle, &wSmplData[j], &ulSmplNum); val = wSmplData[j]; val = ((val * 10) / 4096) - 5; fprintf(fp, "%d, %f\n", i * NUM + j, val); } if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("CSVファイル作成に失敗しました", MB_OK, 0); } } /* デバイスのクローズ */ nRet = AdClose(hDeviceHandle); if(nRet != AD_ERROR_SUCCESS){ AfxMessageBox("デバイスのクローズに失敗しました"); } fclose(fp); } このロジックで出力されたcsvをグラフ化すると添付画像のようなグラフになってしまいます。 データの遅れは何が原因でしょうか?  ご教授よろしくお願いいたします。

  • Sin波をAD変換ボードを通してAD変換したときの波形図。

    Sin波をAD変換ボードを通してAD変換したときの波形図。 AD変換ボードの操作に慣れようと思って、周波数発信機を用いて60Hz、600Hz、6kHz、60kHz、600kHzのsin波を測定しているのですが、60Hz、6kHzのときは、きれいなsin波が測定できるのですが、それ以外の周波数の場合には、sin波が測定できません。一応サンプリング周波数を変えてやってみたのですが、それでもダメでした。60Hzと6kHzの測定はサンプリング周波数1000Hzで取ることができました。こんな現象が起きるのにはサンプリング周波数以外にも何か理由があるのでしょうか? なお、供給する電圧は、2~3V程度の信号を使用しています。 使用しているAD変換ボード:分解能16bit、最高サンプリング速度100kSPS、バイポーラ:±10V 添付図は、電圧は違いますが同じ回路を使用した場合の60Hzと600Hzの波形です。

  • VC++2010、ADボードを用い周波数を出す方法

    VC++2010、ADボードを用い周波数を出す方法を探しているんですが どこを探してもそういうサンプルプログラムがなく困っています。 デバイスをオープンとかファンクションジェネレータからアナログ波形の入力その電圧値を 取得などは出来るんですが、その周波数を出す方法が分かりません。 なにか良い方法、サンプルプログラムなどはありませんか?よろしくお願いします。 ちなみにADボードは12ビットの分解能のPCI3163で、VC++2010でファンクションジェネレータから出力されるアナログ波形のをADボードを経由してもらい、その後 周波数を出す考えでいます。 ちなみにファンクションジェネレータから出力している周波数は80kHzであります。 ではよろしくお願いします。

  • ADボードを購入したいのですが・・・

    実験でアナログのデータを取り込んで,リアルタイムでパソコンに取り込みたいのですが,その際にADボードを購入しようと考えています. PCIバス,OSはWINDOWS98,チャンネル数や解像度にはこだわりません.アナログ出力は±10Vです. だいたい値段の相場はいくらぐらいなのでしょうか. ご存知の方,よろしくお願いします.

  • 卒業研究でプログラムを組むことになりましたが、C++初心者のため戸惑っ

    卒業研究でプログラムを組むことになりましたが、C++初心者のため戸惑っています。 現在困っていることは、CSVファイルのデータ(縦一列)を1行目を読み込み計算、2行目を読み込み計算、3行目を読み込み計算…といった作業をデータの数だけ繰り返し、最終的にCSVファイルに出力するプログラムを組みたいと考えています。 私も引き続きC++を勉強しながら回答お待ちしています。 どうぞよろしくお願いします。

  • PCに挿したIOボードを制御するためのプログラム

    IOボード(AD/DAボード)を使ってPCで入出力制御(例えばモーターのフィードバック制御)をしたいと思っているのですが、ボードにアクセスするためのプログラムや、信号を入出力するためのプログラムをどのように書いたら良いかわかりません。おそらくデータシート?に書いていると思うのですが、知識不足で読み解くことができません。(いままでArduino IDEでArduinoの制御をしたことしかありません。普通にC言語でAVRマイコンをプログラムして制御することはできません。C言語の基礎知識はあります。) そこで質問なのですが、PCから(例えばPCIスロットに挿した)IOボード(AD/DAボード)を制御するための知識は、どのようにして習得できますでしょうか?参考になる本やサイトが見つかりません。PICやAVRなどのマイコンであれば本が色々出ているようなのですが、そのようなマイコンを使えるようになれば、PCからIOボードを制御できる基礎知識は付きますでしょうか?