現在、シリアル通信をする(受信のみ)プログラムを作成しています。
接続先は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など)がでているのでもう少しなにかがたりなさそうです。
初期化などで改善さているのでおそらくデータ格納のところをもう少し改善すればできそうだと思います。
もう少しいろいろやってみます。
一度ここで回答を打ち切りさせていただきます。
いろいろとありがとうございました。
No.5
- 回答日時:
No.1 です。
「バイナリデータでは?」と書いたのは間違っていたわけですが、それでも、
printf("%02x\n",pszBuf[i]);
で、バイナリデータとして確認してみるのは、無駄ではないと思います。
これで、どういうコードとして渡ってきているかは確認できますので。
お返事おそくなり、申し訳ございません。
上のコメントにも書いておりますが、printf("%02x\n",pszBuf[i])をやると
ffffc3みたいなのがでてきました。
もう少しこちらで考えます。
いろいろありがとうございました。
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でてきていました。
No.1
- 回答日時:
とりあえず、
printf("%c\n",pszBuf[i]);
を、
printf("%02x\n",pszBuf[i]);
に変更すると、何か見えてくると思います。
先頭に、0x02, 0x22 が付加されていることから考えても、そのデータは、「バイナリデータ」である可能性が高いと思うわけです。
これは、文字コードの形で送られてくるデータ(テキストデータ)ではないので、("%c" で)文字として表示しても、意味のある表示はできません。
%02x という書式指定子で、まずは、16進のバイナリデータとして表示できますので、これだと、少なくとも、先頭の0x02, 0x22 は見られると思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- ネットワーク OSI参照モデルの各層の役割がわかりません。 3 2023/04/21 21:12
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- 電車・路線・地下鉄 ITパスポート試験問題 7 2023/01/25 09:51
- 固定電話・IP電話・FAX 業務用ファックスについて 5 2022/09/28 19:08
- テレビ テレビが映るまで3~5分かかります 8 2023/04/11 09:47
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- ドライブ・ストレージ RS232C 通信でエラー(受信が正確でない)がでます。どなたか教えてくださいませ。 11 2022/09/03 11:53
- ダイヤルアップ Raspberry Piでアナログモデム経由で音声再生 1 2022/05/20 18:01
このQ&Aを見た人はこんなQ&Aも見ています
-
「環境が人を育てる」って本当?環境によって人格や生き方は本当に変わるのか
環境が人生に与える影響は実際どれほどのものなのか、専門家の田宮由美さんに伺った。
-
シリアル通信でのデータ受信
C言語・C++・C#
-
RS232cを用いた送信プログラム
C言語・C++・C#
-
visual C++ でaruduinoとシリアル通信
C言語・C++・C#
-
-
4
シリアル通信の受信待ちについて
C言語・C++・C#
-
5
シリアル通信でのread関数の戻り値
C言語・C++・C#
-
6
シリアル通信で0x00を送信したいのですが。
C言語・C++・C#
-
7
C言語とシリアル通信の送受信データの概念
C言語・C++・C#
-
8
COMポート 名前を取得する方法
C言語・C++・C#
-
9
C# シリアル通信でデータ受信時の欠損について
C言語・C++・C#
-
10
ソケット通信内 read関数について
C言語・C++・C#
-
11
シリアル通信でのデータ分け
C言語・C++・C#
-
12
数値をASCII文字にする方法についての質問です。
C言語・C++・C#
-
13
Linuxでのシリアル通信についてですが、受信のときにデータがずれた状態で送られてくることがあります
C言語・C++・C#
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
教えて下さい
-
配列でデータが入っている要素...
-
VBA 空白セルを削除ではない方...
-
VBAを使ってOutlookメール本文...
-
この行は既に別のテーブルに属...
-
<VB>String→Object
-
大学のゼミのレポートがムカつ...
-
S9タイプからXタイプにデータ...
-
VBAでシートからコンボボックス...
-
【エクセル】測定時間がバラバ...
-
DataGridViewのデータの引渡し...
-
issetでボタンが押されたかを確...
-
ビットシフトについて
-
シリアル通信でのデータ受信
-
多量のSUMIF式を軽くしたい
-
マクロで同じフォルダにある画...
-
シーケンサにパソコンからアク...
-
DIBフォーマットの読み込みとそ...
-
Winsockで1460Byte以降のデータ...
-
Accessで該当データにフラグを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
教えて下さい
-
配列でデータが入っている要素...
-
【エクセル】測定時間がバラバ...
-
メモ帳(テキストデータ)をExc...
-
VBA 空白セルを削除ではない方...
-
多量のSUMIF式を軽くしたい
-
この行は既に別のテーブルに属...
-
S9タイプからXタイプにデータ...
-
Excelのマクロでワードのテキス...
-
エクセルで2つの時系列のデー...
-
Accessで該当データにフラグを...
-
ユーザーフォームのテキストボ...
-
シーケンサにパソコンからアク...
-
EXCELVBAでSQLserverからデータ...
-
[C言語] コメント文字列を無視...
-
VBAを使ってOutlookメール本文...
-
プログラミング python pandas ...
-
VBA 毎日取得するデータを順番...
-
<VB>String→Object
-
カンマからスラッシュに
おすすめ情報