- ベストアンサー
USB-RS232c変換コネクタを介して通信するC++のプログラム
初投稿になります。 USB-RS232c変換コネクタを介して文字列の送受信するプログラムを作成しているのですが、 こちらのサイト http://7ujm.net/C++/Rs232c.h.html のプログラムを使ったのですが、うまくいきませんでした。 これはUSBを介しているからうまくいかないのでしょうか? どうすれば通信できるようになるか、分かる方教えてください。 ハイパーターミナルでは送受信できているので、 パラメータの設定ミスでは無いと思います。 よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
こんにちは。 #1さんが仰っている内容を、ご理解戴けてますでしょうか? main関数内で呼ばれている、「RS232cクラス」の各メンバ関数は、その関数の 処理の「成功」及び「失敗」の結果を、戻り値(TRUE or FALSE)として返すように なっています。 その戻り値について、プログラム実行時に、 値がどう返されているかを、『実際に見て確かめてみる』 という処置を行ってみては如何でしょうか? ということです。 戻り値を見るためには、各関数の戻り値を変数に格納するようにしておいて、 printf関数などで、その戻り値を出力するようにしておく。 または、 デバッガを使用し、ブレークポイントを設定して、ステップ実行しながら、 途中の戻り値の内容を見てみる。 というような作業が必要です。 それと、ご提示のプログラムの記述内容ですが、幾つか落とし穴(注意点)が あります。 ひとつは、#2さんも仰っていますが、 rs.Connect(); //接続 の記述の仕方。 ⇒引数省略時の各引数のデフォルト値の設定を、下記のように変更されて いるようですが、その設定が通信接続の環境(ハード側の通信仕様)に、 合ったものになっているか? ※引数省略時の各引数のデフォルト値(質問者さんの変更後) char* PortNmae="COM10", int BaudRate = 19200, int ByteSize = 8, int Parity = EVENPARITY, int StopBits = TWOSTOPBIT, int RTS = RTS_CONTROL_DISABLE, int DTR = DTR_CONTROL_DISABLE, int ReadTimeOut =5000, int WriteTimeOut = 20000 ※1番目の引数、「通信ポートのデバイス名」ですが、ポート番号が、10を超えた 場合、下記のような問題があるようです。 ◎CreateFile関数(Win32API)でCOM10以上を使う場合の注意点 http://www.aofactory.net/log/eid328.html ですので、今回の場合のデバイス名は、 "\\\\.\\COM10" のように記述した方が良いかもしれません。 ※下記2つの引数の設定値については、その組合せが正しいかどうか? この設定値により、相手機器との通信が上手く行かない場合があります。 int RTS, //RTSをON=RTS_CONTROL_ENABLE 初期値は無効です int DTR, //DTRをON=DTR_CONTROL_ENABLE 初期値は無効です ※DTRの設定値については、Read_CRLF関数内で呼ばれている、isLink関数 の判定結果に関わってきます。その結果、Read_CRLF関数の処理に影響します。 ※RSTとDTRの組合せについては、実際に全てのパターン(全部で4通り)を 試してみる必要があるかもしれません。 そしてもうひとつは、 printf(w); //文字列表示 の記述の仕方。 こちらは通信とは直接関係しませんが。。。 ⇒printf関数の第1引数は、「書式制御用の文字列」です。 ※従って、受信した文字列バッファ w[] の中身に、もしも書式指定用の文字が、 含まれていた場合に、その動作結果がどうなるかは予測できません。 ここは、例えば、 printf( "%s", w ); のように記述した方が良いかもしれません。 この他にも、注意点があるかもしれません。 以上です。参考になれば幸いです。
その他の回答 (4)
- SilverThaw
- ベストアンサー率32% (260/806)
No.1です。 「動かしたけどうまくいかない」だけというのは確認方法としては問題ありです。 「どこまで動作しているか」を確認することが解決への一番の近道です。 No.3氏にフォローを入れていいただいていますが、 今回はサンプルに「結果」を返す処理が組み込まれているのですから、最低でも、その結果の確認位は行いましょう。 (その意味では、サンプルのmainソースはよろしくありません。動作すること前提で処理を省いてますので) 以下は一例です。 ----------- int main() { RS232c rs; bool result; result = rs.Connect(); //接続 if( result == FALSE ) { printf( "\n Connect Error" ); _getch(); return; } result = rs.Send("test data\x0d\x0a"); //文字列送信 if( result == FALSE ) { printf( "\n Send Error" ); _getch(); return; } char w[100]; memset(w, 0x00, sizeof(w)); //念の為バッファ初期化 result = rs.Read_CRLF(w,99); //文字列受信 if( result == FALSE ) { printf( "\n Read Error" ); _getch(); return; } printf(w); //文字列表示 printf("OK?"); _getch(); return 0; } ----------- >COM10はハイパーターミナルで表示されてたポートをそのまま使いました。 「本当に」COM10がUSB-RS232ですか? デバイスマネージャーでCOMポートを確認してみてください。 USBを接続しない時と、USBを接続した時でCOMポートの数が違っていれば、その違った時に増えているのがUSBで割り当てられたところです。 製品によっては、接続されていない場合でも、仮想的にCOMポートを割り当ててしまう場合があります。 その際には、デバイスマネージャーを「接続別」にしてUSBの接続ツリーを表示するとわかります。 尚、フロー制御ははずしておいたよい場合があります。 あと、No.3氏の > ここは、例えば、 > printf( "%s", w ); > のように記述した方が良いかもしれません。 は受信していても、データが壊れていると正常に表示できないことも考えられるため for( i = 0; i < sizeof(w); i++ ) printf("%02x ", w[i]); のように16進表記でデータを確認するのも一つの手です。
お礼
詳細な一例、ありがとうございます。 非常に参考になります。 ポートについてはデバイスマネージャ上でもCOM10でした。 フロー制御は実はあまりよく分かっていなかったりします・・・。 とりあえず動作の確認はできましたので、この質問はクローズ致します。 また分からないことがあれば質問させていただきます。 ありがとうございました。
#3です。 すみません。 #3の内容について、下記の訂正があります。 【誤】 ※RSTとDTRの組合せについては、実際に全てのパターン(全部で4通り)を 試してみる必要があるかもしれません。 【正】 ※RTSとDTRの組合せについては、実際に全てのパターン(全部で4通り)を 試してみる必要があるかもしれません。 失礼致しました。
お礼
わざわざご丁寧にありがとうございます。
- D-Matsu
- ベストアンサー率45% (1080/2394)
> rs.Connect(); //接続 オープンするCOMポートがデフォルトなのでCOM1のままです。 #RS232Cクラスの定義を書き換えてるのでなければ ちゃんとUSB変換ケーブルに割り当てられたCOMポートを開くようにConnect()に引数渡してやりましょう。
補足
ご回答ありがとうございます。 すみません、RS232c.hも修正していました。 ソースは以下になります。 bool RS232c::Connect(char* PortNmae="COM10", int BaudRate = 19200, int ByteSize = 8, int Parity = EVENPARITY, int StopBits = TWOSTOPBIT, int RTS = RTS_CONTROL_DISABLE, int DTR = DTR_CONTROL_DISABLE, int ReadTimeOut =5000, int WriteTimeOut = 20000 ) COM10はハイパーターミナルで表示されてたポートをそのまま使いました。
- SilverThaw
- ベストアンサー率32% (260/806)
>のプログラムを使ったのですが、うまくいきませんでした。 「うまくいかない」のはどういったところですか? 参考のソースには、それぞれ戻り値として実行結果を送るようになっています。 どこまでが動作しているのでしょうか? それも確認せずに「うまくいかない」といっているのでは、対処しようがないですよ。
補足
ご回答ありがとうございます。 すみません、内容が不足していましたね・・・。 コンパイルまではできるのですが、実行しても受信データが帰ってきませんでした。 ↓のプログラムで、画面にOK?としか表示されません。 #include "RS232c.h" #include "stdafx.h" #include <stdio.h> #include <conio.h> int main() { RS232c rs; rs.Connect(); //接続 rs.Send("test data\x0d\x0a"); //文字列送信 char w[100]; rs.Read_CRLF(w,99); //文字列受信 printf(w); //文字列表示 printf("OK?"); _getch(); return 0; }
お礼
ご回答ありがとうございます。 そして返事が遅くなってしまって申し訳ありません。 どうにも勘違いをしていたようです。 確かに、一つ一つ挙動を確認しないと原因に辿り着けませんね…。 どうも、ポートのデバイス名が10だったのが原因だったようです。 "\\\\.\\COM10"に変更したら正常に動作しました。 ありがとうございます。