![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
現在、シリアル通信をする(受信のみ)プログラムを作成しています。
接続先は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 …
No.4ベストアンサー
- 回答日時:
>一応、ReadFileをおわったあとにdwReadを確認したのですが、50になっていました。
であれば、ReadFile()が失敗したとかはなさそうですね。
# ReadFile()の戻り値を確認していないのであればdwReadはReadFile()コール前にクリアしておいた方がいいかと思いますが。
>なんらかの失敗といわれるとどういった失敗がありえるのでしょうか?
タイムアウトがないのであれば…基本的には失敗はない…でしょうね。
コネクタ類が接触不良でデータが化けるとか、XON/XOFFフロー制御している…とかでなければ。
>(ボーレートの設定がおかしければデータがかわることはあるでしょうが・・・)
ボーレート以外の設定が異なっていた場合も化けると思われます。
>接続先がデータを送らなくとも、ReadFileがデータを格納することがあるのでしょうか?
受信バッファに残っていた場合は読み出す…でしょうね。
CreateFile()でシリアルポートを開く処理、シリアルポートの設定を行っている部分も掲示された方がいいかも知れません。
# が、私自身はAPI叩いてシリアルポート操作したことは無かったりします。
WindowsAPIのパターンとして…構造体は0x00でクリアして必要な部分だけ設定する。
という方法を採らないと妙な挙動することもありますので、その辺りは確認された方がいいでしょう。
APIに構造体のアドレスを渡して、情報を取得(上書きされる)から…ということで、未初期化の構造体渡したらエラーで何も設定してくれなかった。
なんて場合もあります。
# 構造体のメンバに「構造体のサイズ」を格納する場合、その構造体のサイズで対応バージョンを判別する。
# なんて挙動をしている場合もありますので。
お返事遅くなり、申し訳ございません。
とりあえず、初期化などをおこなうと周期的に0x2B, 0x22がでるようになりました。
ただ、出力されるはずのないマイナスの値(ffffc3など)がでているのでもう少しなにかがたりなさそうです。
初期化などで改善さているのでおそらくデータ格納のところをもう少し改善すればできそうだと思います。
もう少しいろいろやってみます。
一度ここで回答を打ち切りさせていただきます。
いろいろとありがとうございました。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_02.png?e8efa67)
No.5
- 回答日時:
No.1 です。
「バイナリデータでは?」と書いたのは間違っていたわけですが、それでも、
printf("%02x\n",pszBuf[i]);
で、バイナリデータとして確認してみるのは、無駄ではないと思います。
これで、どういうコードとして渡ってきているかは確認できますので。
お返事おそくなり、申し訳ございません。
上のコメントにも書いておりますが、printf("%02x\n",pszBuf[i])をやると
ffffc3みたいなのがでてきました。
もう少しこちらで考えます。
いろいろありがとうございました。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_02.png?e8efa67)
No.3
- 回答日時:
#1 です。
> 0x02, 0x22ではなく0x2B, 0x22のようですので文字列かと。>#1
確かに。0x02 をバイナリデータでよく使うので、思わず見間違えていました。
お恥ずかしい。
No.2
- 回答日時:
>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でてきていました。
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_02.png?e8efa67)
No.1
- 回答日時:
とりあえず、
printf("%c\n",pszBuf[i]);
を、
printf("%02x\n",pszBuf[i]);
に変更すると、何か見えてくると思います。
先頭に、0x02, 0x22 が付加されていることから考えても、そのデータは、「バイナリデータ」である可能性が高いと思うわけです。
これは、文字コードの形で送られてくるデータ(テキストデータ)ではないので、("%c" で)文字として表示しても、意味のある表示はできません。
%02x という書式指定子で、まずは、16進のバイナリデータとして表示できますので、これだと、少なくとも、先頭の0x02, 0x22 は見られると思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
【お題】甲子園での思い出の残し方
「球場の砂を持って帰る」はもう古いと思った高校球児が、甲子園で負けた際に、思い出に残そうと思って行ったこと
-
RS232cを用いた送信プログラム
C言語・C++・C#
-
シリアル通信でのデータ受信
C言語・C++・C#
-
シリアル通信の受信待ちについて
C言語・C++・C#
-
-
4
シリアル通信でのread関数の戻り値
C言語・C++・C#
-
5
シリアル通信で0x00を送信したいのですが。
C言語・C++・C#
-
6
visual C++ でaruduinoとシリアル通信
C言語・C++・C#
-
7
数値をASCII文字にする方法についての質問です。
C言語・C++・C#
-
8
C言語とシリアル通信の送受信データの概念
C言語・C++・C#
-
9
WriteFile()でのデータ送信ができなくなる
C言語・C++・C#
-
10
C# シリアル通信でデータ受信時の欠損について
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA 円グラフ 特定条件に一致し...
-
【エクセル】測定時間がバラバ...
-
エクセルで2つの時系列のデー...
-
教えて下さい
-
S9タイプからXタイプにデータ...
-
配列でデータが入っている要素...
-
EXCELVBAでSQLserverからデータ...
-
特定のデータの抽出方法を教え...
-
ExcelデータをVB.netで検索する...
-
メモ帳(テキストデータ)をExc...
-
Matlab:plotで特定の値だけをプ...
-
シリアル通信プログラム(受信...
-
Data(加算名詞、不可算名詞)に...
-
AccessからExcelを編集
-
チェックサムの実装方法について
-
ExcelVBAでデータ不一致のもの...
-
C# でDataTableの更新を高速化...
-
VBAを使ってOutlookメール本文...
-
多量のSUMIF式を軽くしたい
-
ActiveReportについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
教えて下さい
-
配列でデータが入っている要素...
-
あんまり考えたくないけど
-
【エクセル】測定時間がバラバ...
-
メモ帳(テキストデータ)をExc...
-
多量のSUMIF式を軽くしたい
-
この行は既に別のテーブルに属...
-
エクセルで2つの時系列のデー...
-
ブレーカー落ちで壊れたりしな...
-
VBA 空白セルを削除ではない方...
-
S9タイプからXタイプにデータ...
-
Accessで該当データにフラグを...
-
EXCELVBAでSQLserverからデータ...
-
CString型の文字列連結について
-
[C言語] コメント文字列を無視...
-
VBAを使ってOutlookメール本文...
-
シーケンサにパソコンからアク...
-
C# ソケット通信でデータ受信時...
-
パースとはなんですか?
-
ユーザーフォームのテキストボ...
おすすめ情報