教えてください。。。
シリアル受信を行っているのですが、大量のデータを受信しています。
(example:10msごとに20byteのデータを10秒間受信)
無限ループでReadFileを実行し、1byteずつWindowsバッファから取り出し、自分のバッファに積んでいます。
すると途中で正しい文字が積まれないことがあります。
前後は正しく取り出せているのに、途中で1byteだけ抜けてしまうことがあります。
外部から送られてくるデータが正常に送られていることは確認しました。
Windowsバッファのサイズが小さいかと思い、十分に大きい値にしてみましたが解消されません。
また、ReadFile、ClearCommErrorの戻り値が0にもなりません。
何か考えられることはありますか?
よろしくお願い致します。
ちなみに以下がWindowsバッファからの読み込み部分です。
------------------------------------------------------
DWORD dw;
COMSTAT Cs;
char data[2];
int num = 0;
BOOL tst;
tst = ClearCommError(Handle, &dw, &Cs);
if(tst == 0) AfxMessageBox("ERROR");
tst = ReadFile(Handle, (LPVOID)data, 1, &num, NULL);
if(tst == 0) AfxMessageBox("ERROR");
1byte抜けるという表現がよくありませんでした。
たとえば、0x01が送られてきているのに、Windowsバッファから取り出すと0x00になっているということです。
0x00になってしまうことがほとんどです。
よろしくお願い致します。
うまくいかない原因がソフト側にあるのかハード側にあるのか、はっきりしたことが判明済みなのかな?
ソフトが正しくてもハード側でデータ化けが起きているかもしれない。
とりあえず受信しかしないのであれば TeraTerm なり HyperTermina なりで受信+ログ保存してみるといい。
別なツールで期待通りの受信データが得られているのであれば自作ソフトが悪いわけだし
得られないのであればハードウェア側に何か問題があるといえそうだ
話はそれから
2000[Byte/s]×10[s]なら、たかだか20000Byteのバッファを
用意すれば良いだけのような気がします。
まず、1ターン分の全データを一気に受信してみて、
異常が無いことを確認しましょう。
これでデータ内に異常があるなら、プロトコルや
外乱を疑うべきかもしれません。
中間バッファを設けるのはその後の工程ですね。
tetrapodさん、仲澤@失業者さん
ありがとうございます。
tetrapodさんの仰る通り、タームを使用して確認したところ問題なく動作しています。
しかし、VC++にて読み込むと何回やっても"抜けて"しまいます。
USB-RS232変換器を使用していますので、変換器を別のメーカーのものに変更したところ問題なく動作しました。
タームでは問題ありませんでしたので変換器自体に問題があるとは思えませんが、ググっても同じような症状の報告はありませんでした。。。
となると、私のプログラムが悪いように思われますが、他メーカーのものですと問題なく動作していますし・・・。
ClearCommError()後のCs.cbInQueやReadFile()後のnumの値のチェックはしていますか?
ゼロでも何か受信したと思って処理してしまい、化けているように見えるとか。
でもそれだと化けた上でデータがずれていくか……
もう解決済みなので見ていないかもしれませんが・・・。
※USBシリアル変換ICの製作者でも、デバイスドライバの
製作者でもないので、以下勘違いがあるかもしれません。
USBシリアル変換器には、USBシリアル変換ICが使われて
いるんですが、物によって内蔵のバッファメモリ容量に
差があるようです。
ドライバーの作りの問題なのか、機器側からバッファ容
量以上のデータをまとめて送信し、PC側に取得してない
データがバッファ容量以上に溜まった場合に取りこぼす
(おそらくIC内でバッファオーバーフローしてる?)
USBシリアル変換ICがありました。
従って、同じ様に1バイトずつ取得している間にIC側で
バッファでオーバーフローが発生してるんではないで
しょうか?
yoh2さん、ひでらんさん
ありがとうございます。
numの値はチェックしています。Cs.cbInQueはチェックしていませんでしたが、文字がずれるわけではなく一文字だけ0x00に化けるんですよね。
それ以降はまた正常に受信します。。。
ひでらんさんの仰るようにUSB変換器のICが原因かと思いますが、
38400bpsで20byteデータを送信していますので、約5msで送信します。
これをPC側で読みだすのにそんなに時間はかからないと思います。
実際エラーが起きたときは20byteデータを100ms毎に送信してもエラーが起きましたが、PC側で読みだすのに95msもかからないと思いますし。。。
この問題は結果的にVC++をは違ったことになってしまいました。
申し訳ありませんでした。
ツイート | ![]() |