プロが教えるわが家の防犯対策術!

シリアル通信にてデータを連続的に受信するプログラムを
つくりたいと思っています.

以下のプログラムを作成して,
main関数のcountを増やして,繰り返しreadを行おうとすると,

出力結果として,
時,分,秒,ID,値B,値C,値Dというフォーマットで

0, 9,30, 1,514,708,542,290

0, 9,30, 2,515,707,542,288

0, 9,30, 3,514,709,542,287

0, 9,30, 4,514,707,543,289

0, 9,30, 5,514,708,542,289

0, 9,30, 6,514,708,542,292

0, 9,30, 7,514,708,542,291

0, 9,30, 8,514,708,542,289

0, 9,30, 9,514,708,543, 0, 9,39,35,514,708,542,289

(この後フが連続)
フフフフフフフフフフフフフフフ ク 0, 9,39,36,514,708,542,290

0, 9,39,37,515,709,541,291

0, 9,39,38,514,707,542,286

0, 9,39,39,514,708,542,281

0, 9,39,40,514,708,542,284

0, 9,39,41,514,707,542,286

0, 9,39,42,514,707,542,290

0, 9,39,43,514,709,542,290

0, 9,30, 9,514,708,543, 0, 9,39,35,514,708,542,289

フフフフフフフフフ・・・再びフ

となってしまいます.
問題としては

・フがたくさんでてきてしまう.
・1サイクルの最後で改行ができていない
・1サイクルが終わって次のサイクルに入る時までの
間にデータが失われている.
・2サイクル目になぜか1サイクル目の値が残っている?

などがあります.

どなたか解決方法を教えていただけると大変助かります.
よろしくお願いします.
-------------------------------
#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#include <stdio.h>

#define COM_PORT_NAME"COM2"
#define BAUD_RATE57600
#define BYTE_SIZE5000 //250
#define PARITYNOPARITY //EVENPARITY
#define STOP_BITTRUE
#define F_PARITYONESTOPBIT

HANDLE hComm;// シリアルポートとの通信ハンドル

bool ComInit()
{
// シリアルポートを開ける
hComm = CreateFile(
COM_PORT_NAME,/* シリアルポートの文字列 */
GENERIC_READ | GENERIC_WRITE,
/* アクセスモード:読み書き */
0,/* 共有モード:他からはアクセス不可 */
NULL,/* セキュリティ属性:ハンドル継承せず */
OPEN_EXISTING,/* 作成フラグ: */
FILE_ATTRIBUTE_NORMAL,/* 属性: */
NULL/* テンプレートのハンドル: */
);

if (hComm == INVALID_HANDLE_VALUE) {
printf("シリアルポートを開くことが出来ませんでした。\n");
return false;
}

// 通信属性を設定する
DCB dcb;
GetCommState(hComm, &dcb); /* DCB を取得 */
dcb.BaudRate = BAUD_RATE;
dcb.ByteSize = BYTE_SIZE;
dcb.Parity = PARITY;
dcb.fParity = STOP_BIT;
dcb.StopBits = F_PARITY;
SetCommState(hComm, &dcb); /* DCB を設定 */

return true;
}

void ComEnd()
{
// ハンドルを閉じる
CloseHandle(hComm);
}


bool ReadData(char *buff, unsigned int max_size)
{
DWORD dwErrors; /* エラー情報 */
COMSTAT ComStat; /* デバイスの状態 */
DWORD dwCount; /* 受信データのバイト数 */
DWORD dwRead; /* ポートから読み出したバイト数 */

ClearCommError(hComm, &dwErrors, &ComStat);
dwCount = ComStat.cbInQue;

FILE *fid;
fid=fopen("test.txt", "w");

printf("%d %d\n", dwCount, max_size);
fprintf(fid,"%d %d\n", dwCount, max_size);

fclose(fid);
if (dwCount > max_size) {
printf("バッファサイズが足りません。\n");
return false;
}

if(hComm != NULL){
ReadFile(hComm, buff, dwCount, &dwRead, NULL);

if (dwCount != dwRead) {
printf("データの受け取りに失敗しました。\n");
return false;
}
}

return dwRead;
}

int main(int argc, char* argv[])
{

char buff[BYTE_SIZE];
int count = 0;
int data_length;
FILE *fid2;
fid2=fopen("test2.txt","w");

ComInit();

while(1){
if(count == 2) break;
count++;

data_length=ReadData(buff, strlen(buff));
printf("%s ",buff);
fprintf(fid2, "%s ",buff);


}
fclose(fid2);
ComEnd();

return 0;
}

A 回答 (4件)

先ほどの訂正と追加です。


3.dcb.Bytesizeを8にして、while文を無限ループにし
(countのif~break文を削除し), strlen(buff)のところを
BYTE_SIZEにしてみてください。データが取りこぼしなく
表示されませんか。
#通信が終わらないという問題は、受信ができない問題
とは別問題なので、今は考えていません
4.3.でデータの取りこぼしがあれば、送信側・受信側とも、
BaudRateを低く(9600bpsとか)してみて改善されるかどうか、
確認してください。

データの取りこぼしが通信速度によるものなら、フロー制御など
も考えないといけませんね。ところで、今頃聞くのもなんなんですが、
送信側・受信側は、どのような環境をお使いなんでしょう?
    • good
    • 0

もう少し具体的に情報を書いてもらったほうが、


回答するのが楽になります。
とりあえず、以下の点については、どうでしょうか?

確認事項
1.COM2に正常にデータが送信されてきていますか?
 (ハイパーターミナル等を起動して、データ受信を確認する)
2.dcb.Bytesizeを7、8にすると受信に失敗するとありますが、
 具体的にはどういう風に失敗するのでしょうか?
#やはり5000という値は、おかしいと思います。
 なぜに5000?化けたり、ロストとしたりは、
  この辺りが原因のような気もしますが。
3.dcb.Bytesizeを8にして、while文を無限ループにし
(countのif~break文を削除し), strlen(buff)のところを
100とすると、受信したデータが画面に表示されませんか?
    • good
    • 0

#defineでSTOP_BITとF_PARITYの名前と値の対応関係がおかしい気がしますが、


とりあえず、値をセットする側でうまく(?)吸収されてますね。

ところで、dcb.ByteSizeが5000になりますが、ここは、1バイトのビット数を
指定する場所ですね。通常7か8を指定するはずですが、5000としているのは、
何か理由があるのでしょうか。

また、main関数のReadData(buff, strlen(buff))の部分ですが、buffが
初期化されていないので、strlen(buff)がどのような値になるかわからない
気がするのですが、その辺りはいかがですか。

strlen(buff)の部分を100とかの固定値にすると、結果はどのようになりますか?

シリアル通信について、私も初心者なので、この辺りからのアプローチしか
できませんが、問題解決の一助になれば幸いです。
    • good
    • 0
この回答へのお礼

たびたびありがとうございます.
お礼が遅くなり申し訳ありません.

dcb.bytesizeを7あるいは8とすると
データの受け取りで失敗してしまうのです・・・

お礼日時:2007/05/06 12:42

ReadFileで取得したデータの最後に、


buff[dwRead] = '\0';
を忘れているから、print文でおかしな場所まで
表示してしまっているのではないでしょうか。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます.
確かに配列の文字列の最後を記すのを
わすれていました.ありがとうございます.
\0をつけてみました.

フの表示はなくなったのですが,
今度は各行の先頭に■がつくようになりました.

また,データがサイクルごとにロストする.

のはなおっていません.

お礼日時:2007/04/28 11:23

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています