アプリ版:「スタンプのみでお礼する」機能のリリースについて

現在、シリアル通信をする(受信のみ)プログラムを作成しています。
接続先は1秒ごとに10バイトのデータを自動で送信してきます。
現段階でPC側でデータを受信できることは確認できました。
しかし、受信データが文字化け(出力結果が{や■などがでています)しており、その原因がわかりません。
どこが問題なのか教えていただけないでしょうか?

また、接続先からは10バイトのうち最初の2バイトは固定の値(0x2b,0x22)がでてくるはずなのですが、それもでてきていません。これも文字化けで見えていないだけでしょうか?
文字化けしても周期的に固定の値に対応した文字がでてくるものだと思ったのですが、でてきていません。
(ソースで50バイトまでみているのはこの周期性を確認するためです)

シリアル通信を初めてさわるので、考え方自体間違っているかもしれませんが
配列pszBufに1つずつ、受信された1バイトのデータが格納されていると思っています。
個人的にはprintfでの表記(%cがいけない?)に間違いがあるかと疑っています。

ご回答よろしくお願いいたします。

(環境)
Visual C++ 2008 (C/C++)

(シリアルポート設定)
ボーレート 9600bps
パリティ   なし
ストップビット 1
データビット 8

(ソース) ※ポートの設定は省略。受信部のみ記述
HANDLE hComm;
DWORD dwErrors;
COMSTAT ComStat;
char pszBuf[1024];
DWORD dwRead;

ClearCommError(hComm, &dwErrors, &ComStat);
ReadFile(hComm, pszBuf, 50, &dwRead, NULL);  //50バイトまでデータを取得

for(int i=0;i<50;i++){
printf("%c\n",pszBuf[i]);
}

(参考URL)
http://www.geocities.jp/terukat/_geo_contents_/w …

A 回答 (5件)

>一応、ReadFileをおわったあとにdwReadを確認したのですが、50になっていました。



であれば、ReadFile()が失敗したとかはなさそうですね。
# ReadFile()の戻り値を確認していないのであればdwReadはReadFile()コール前にクリアしておいた方がいいかと思いますが。

>なんらかの失敗といわれるとどういった失敗がありえるのでしょうか?

タイムアウトがないのであれば…基本的には失敗はない…でしょうね。
コネクタ類が接触不良でデータが化けるとか、XON/XOFFフロー制御している…とかでなければ。

>(ボーレートの設定がおかしければデータがかわることはあるでしょうが・・・)

ボーレート以外の設定が異なっていた場合も化けると思われます。

>接続先がデータを送らなくとも、ReadFileがデータを格納することがあるのでしょうか?

受信バッファに残っていた場合は読み出す…でしょうね。

CreateFile()でシリアルポートを開く処理、シリアルポートの設定を行っている部分も掲示された方がいいかも知れません。
# が、私自身はAPI叩いてシリアルポート操作したことは無かったりします。

WindowsAPIのパターンとして…構造体は0x00でクリアして必要な部分だけ設定する。
という方法を採らないと妙な挙動することもありますので、その辺りは確認された方がいいでしょう。
APIに構造体のアドレスを渡して、情報を取得(上書きされる)から…ということで、未初期化の構造体渡したらエラーで何も設定してくれなかった。
なんて場合もあります。
# 構造体のメンバに「構造体のサイズ」を格納する場合、その構造体のサイズで対応バージョンを判別する。
# なんて挙動をしている場合もありますので。
    • good
    • 0
この回答へのお礼

お返事遅くなり、申し訳ございません。
とりあえず、初期化などをおこなうと周期的に0x2B, 0x22がでるようになりました。
ただ、出力されるはずのないマイナスの値(ffffc3など)がでているのでもう少しなにかがたりなさそうです。
初期化などで改善さているのでおそらくデータ格納のところをもう少し改善すればできそうだと思います。

もう少しいろいろやってみます。
一度ここで回答を打ち切りさせていただきます。
いろいろとありがとうございました。

お礼日時:2015/01/11 23:22

No.1 です。


「バイナリデータでは?」と書いたのは間違っていたわけですが、それでも、

printf("%02x\n",pszBuf[i]);

で、バイナリデータとして確認してみるのは、無駄ではないと思います。
これで、どういうコードとして渡ってきているかは確認できますので。
    • good
    • 0
この回答へのお礼

お返事おそくなり、申し訳ございません。
上のコメントにも書いておりますが、printf("%02x\n",pszBuf[i])をやると
ffffc3みたいなのがでてきました。

もう少しこちらで考えます。
いろいろありがとうございました。

お礼日時:2015/01/11 23:27

#1 です。



> 0x02, 0x22ではなく0x2B, 0x22のようですので文字列かと。>#1

確かに。0x02 をバイナリデータでよく使うので、思わず見間違えていました。
お恥ずかしい。
    • good
    • 0

>ReadFile(hComm, pszBuf, 50, &dwRead, NULL);  //50バイトまでデータを取得



ReadFile()は50バイト読み込みが完了するまで絶対に戻ってこない。
という認識でよろしいですか?
タイムアウトで戻って来るとか、なんらかの失敗はあり得ない。
という前提のコードですけど。

ReadFile()の戻り値の確認をしていなかったり、第4引数で渡した変数の内容は無視して50回のループをまわしたり…というのはそういう意図であると読めますが…。
ReadFile()で1バイトも読み込めずに失敗した場合、第2引数で渡したバッファの中身はどうなりますかね?
# ReadFile()に渡す前にmemset()などで意味のある初期化をしておく…というのも手かと思われますよ。
# 後で文字列として扱いたいなら'\0'で埋めておく…とか。


当たり前ですが、送信元が問題ない場合…ですので、TeraTermなどで正常に受信できる。
というのは予め確認しておいた方がいいかと思います。


0x02, 0x22ではなく0x2B, 0x22のようですので文字列かと。>#1

この回答への補足

asano_nagiさん、Wr5さん
お返事遅くなり申し訳ございません。
ご回答ありがとうございました。
>ReadFile()は50バイト読み込みが完了するまで絶対に戻ってこない。
>という認識でよろしいですか?
はい、そのとおりです。

まず、タイムアウトは考えずにわざと50バイトのデータがくるまで待つようにしています。これは接続先が1秒ごとに10バイトのデータをおくるので、タイムアウトの設定をしなければ、いつかは必ず50バイトのデータが送られてくると
思ったからです。一応、ReadFileをおわったあとにdwReadを確認したのですが、50になっていました。

>タイムアウトで戻って来るとか、なんらかの失敗はあり得ない。
なんらかの失敗といわれるとどういった失敗がありえるのでしょうか?
私の考えでは、接続先がPCにデータを1秒ごと10バイトおくっているだけなので、その間にデータが変化することはないと思ったんですが・・・

たとえば、接続先が(0x2B, 0x22,0x4B, 0x32,0xB3・・・)というデータをPCに送ったとき、PCがうけとるときに(0x2B, 0x00,0x22,0x40, 0x32,0xB3・・・)のようにデータが増えたり、データ自体がかわってしまうということもありえるのでしょうか?(ボーレートの設定がおかしければデータがかわることはあるでしょうが・・・)
接続先がデータを送らなくとも、ReadFileがデータを格納することがあるのでしょうか?

># ReadFile()に渡す前にmemset()などで意味のある初期化をしておく
これは一回やってみます。
>当たり前ですが、送信元が問題ない場合…ですので、TeraTermなどで正受信できる。というのは予め確認しておいた方がいいかと思います。
ハイパーターミナルで確認しております。0x2B, 0x22でてきていました。

補足日時:2015/01/08 20:43
    • good
    • 0

とりあえず、


printf("%c\n",pszBuf[i]);
を、
printf("%02x\n",pszBuf[i]);
に変更すると、何か見えてくると思います。

先頭に、0x02, 0x22 が付加されていることから考えても、そのデータは、「バイナリデータ」である可能性が高いと思うわけです。
これは、文字コードの形で送られてくるデータ(テキストデータ)ではないので、("%c" で)文字として表示しても、意味のある表示はできません。

%02x という書式指定子で、まずは、16進のバイナリデータとして表示できますので、これだと、少なくとも、先頭の0x02, 0x22 は見られると思います。
    • good
    • 0

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

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


このQ&Aを見た人がよく見るQ&A