VISCAプロトコル(RS232C通信)で、やはり長いコマンドを正しく送れない
次のサイトのソースをもとに、SONY EVI-HD1カメラをPCからVC++プログラムで制御しようとしています:
http://onishi-lab.jp/programming/rs232c_win.html
ただし、以前あった以下の質問を参考に、ソースをいくつか修正しています:
http://okwave.jp/qa/q4296092.html
具体的には、下記の変更を加えました:
(1)"sprintf"ではなく"memcpy"関数を使うようにする
(2)"dcb.fOutxDsrFlow = bSet;"の部分は"bSet = dcb.fOutxDsrFlow;" の誤りと思われるので修正
以前の質問では(1)の修正により解決されたようでしたが、実際に試してみると問題がありました。
これは、前の方が質問の中で報告されている通り、
「短いコマンド(例:カメラを右にパンする、81 01 06 01 10 10 02 03 FF)は動くが、長いコマンド(例:カメラのパンチルト上限を設定、81 01 06 07 00 01 0F 0A 05 00 0F 0E 09 08 FF)になるとコマンド中に00が入ると動かない。また、コマンド中に0がなくても思うような動きをしない」
というものです。
私が試したところ(1)の修正に関係なく、上の問題が発生するようです。
・なぜ長いコマンドになると問題があるのか?
・なぜ00が入るとコマンド書き込みが上手くいかないのか?
など見当がつかず、混乱しております。
もし何か心当たりがありましたら教えていただければ大変助かります。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
No.1です。
原因がわかられて何よりです。
ちょっとだけ追加でアドバイスです。
質問文と
>memcpyを使っていても,結局データの一部がNULL文字扱いになっていたことが原因だったようです.
からだと「通信データフォーマットを理解していなかった」と理解することができてしまいます。
誤解がないようにしていただきたいのですが、「RS-232c」は「通信のI/F(H/W)の規格」であって「通信データの規格ではない」ということです。
(さらに厳密にいえば、「RS-232」のRev.cなので「RS-232c」となるのですが)
従って、「通信データ」として「0x00」を送ることは可能です。
No.1では「『プログラム内での』送信データは正しいもの」としてプロトコルアナライザー(ラインモニタ)での確認を勧めましたが、
今回の問題はその手前だったようなので通信系の確認すべき個所を再度纏めておきます。
・(プログラムとして)送信するデータが正しいかどうか
→H/Wになるべく近いレイヤ(今回ならWriteFile直前)で内容を確認
・ライン上の送信データが正しいかどうか
→プロトコルアナライザー(ラインモニタ)で確認
・受信されたデータが正しいかどうか
→受信側デバイスで確認できなくても、
大抵は受信側デバイスから正常に受信できたかどうかの返答があるのでそれで確認
・根本的に送受信の設定があっているか
→ラインにクロック信号が無い場合や、データにクロックを埋め込んでいない場合は特に重要。
上記を確認する際に必要となる情報が「通信データフォーマット」ということになります。
No.3
- 回答日時:
ちょっと参考までにコメント
コマンド送ったあとにACKとか何か返ってきてますよね?
それはどんな内容なんでしょうか?コマンド成功、失敗とも確認した方がいいと思います。
また、bSet=0とかにしてXフローはOFFなんですか?場合によっては誤動作する可能性があるのでチェックが必要かも。
No.2
- 回答日時:
短いコマンドではデータ中に0があっても無くても動くのでしょうか?
※ 短いコマンドでそのようなデータが作れなかっら確認できませんが
0のデータが入っているときにうまく動かないってのは御自身の
提示URLに書かれてる中に回答が書かれてると思います
(元のサンプルコード自体がテストしてるとは思えないレベルのソースってのがかなりきつい)
>コマンド中に0がなくても思うような動きをしない
ということから何らかの通信トラブルが発生しているのではないかと
思いますが単純に考えられるのは送信オーバランなどですが
結局エラーコードなどを調べた上で何処に問題あるのか
特定する必要があります
#1さんも書かれてるようにプロトコルアナライザお持ちであれば
使うのが確実ですがそんなに安いものでもないので
個人ベースではなかなか手も出せないでしょう
やっぱりシェアウエアになってしまいますが
似たようなことも出来るツールの紹介として
http://www.fukufukudenshi.com/
以前はプロトコルアナライザ使ってましたが此方のソフト
使い出してからはPCだけで事足りる方が多くなりました
ご回答どうもありがとうございます.
#1さんへのお礼の中でも報告させていただいた通り,実はコマンドを一旦stringとして格納していたことが原因でした.
そのため,たとえmemcpyを使っても,0がNULL文字として扱われてしまっていたようです.
また,それが分かった後で色々と再確認してみると「長い文字列では0がなくてもおかしい」というのはそのように見えていただけで正確ではなく,長くても短くても「0」の有無が効いていることが分かりました.
色々と確認不足があったり,また最初の質問で上記に関する情報を省略していたりと,恥ずかしい限りですが,勉強になりました.
また,今回の質問がきっかけでプロトコルアナライザについて知ることができました.
教えていただきとても感謝しております.
シェアウェアですが,今後のことを考えてプロトコルアナライザの導入も考えてみようと思います.
ご親切な回答をいただきどうもありがとうございました.
No.1
- 回答日時:
色々と考えられることはあるのですが、とりあえず
WriteFile()の戻り値は確認してください(正確にはエラー発生時に取得したGetLastErrorの値)。
戻り値や引数でエラー値が取得できる関数を使用しているにも関わらず、これを使用して確認をしないのは原因追及にはなりません。
さて、原因推測です。
・デバイス、PCのボーレート等の設定ミス
・USB-232c変換ケーブルを使用している為必要線が動作していない
・デバイスがある一定以上のデータ長のデータを受信できない
・その他の要因
何処まで動作しているのか確認するためには別の類似質問でも回答したことがありますが、
「プロトコルアナライザー」でラインを見るのが確実なのですが……
そうしないと、通信関連は全てそうですが
・そもそもPCから送信されていない
・送信されているがデータがおかしい
・送信データは正しい→受信側の問題
というのが切り分けられません。
素早いご回答をいただき,心より感謝いたします.
アドバイスをもとに原因を探ってみたところ,初歩的なミスであることがわかりました.
実は,関係がないと思い質問の中に書いていなかったのですが,サンプルプログラムにほかの修正も加えていました:
memcpy()の中に直接コマンド文字列を書くのではなく,一旦stringクラス変数として格納してc_str関数で読み出していました.
そのため,memcpyを使っていても,結局データの一部がNULL文字扱いになっていたことが原因だったようです.
stringクラスの仕様を理解していなかったことによる,恥ずかしいミスでした.
また,上記のようなことを最初の質問で書かなかったことも反省しております.
これは,最初にWriteFile関数の戻り値を確認していたのですが,そのとき戻り値が1だったためWriteFile()以降に問題があると早合点してしまったことによるものでした.
その他,ボーレートやケーブル,デバイスの受信できるデータ長なども念のため確認しましたが,これらは問題ありませんでした.
プロトコルアナライザーについては,今まであまり知らなかったのですが,今後のためにも詳しく調べてみたいと思います.
丁寧に対応していただき,どうもありがとうございました.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・【大喜利】【投稿~1/31】『寿司』がテーマの本のタイトル
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ネットワークフォルダの中身を...
-
バッチファイル pause時の文字...
-
コマンドボタンテキストの改行
-
Teratermマクロの戻り値の取得失敗
-
Visual C++からftpを使う
-
RPGでのダメージの算出方法につ...
-
テキストボックスのフォーカス...
-
VBで定期的にタイムサーバに時...
-
teraterm文字列の選択
-
クリックしたボタンによってSel...
-
コマンドプロンプトで印刷実行
-
Worksheet_BeforeClick
-
Windowsのバッチファイルでcall...
-
popen使用時のエラー出力を出し...
-
telnetで接続した先のコマンド...
-
VISCAプロトコル(RS232C通信)...
-
system関数のエラー検出
-
WINSOCKでTCPのステータスを調...
-
scilabのグラフの表示について
-
VBSで指定した時刻にメッセージ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Visual C++からftpを使う
-
ユーザーフォーム内のテキスト...
-
system関数のエラー検出
-
Teratermマクロの戻り値の取得失敗
-
Windowsのバッチファイルでcall...
-
テキストボックスのフォーカス...
-
シリアル通信でのread関数の戻り値
-
ネットワークフォルダの中身を...
-
コマンドプロンプトで印刷実行
-
VBで定期的にタイムサーバに時...
-
バッチ(Windows2000)での解析エ...
-
データリーダーからのデータ読...
-
EXCELで右クリックメニューの追加
-
バッチファイル pause時の文字...
-
SDカードの初期化について
-
コマンドプロンプトでサービス...
-
FlashROMにデータを書き込むに...
-
クリックしたボタンによってSel...
-
bashコマンドの最後の引数
-
C# mciSendStringでエラーコー...
おすすめ情報