
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で質問しましょう!
似たような質問が見つかりました
- その他(開発・運用・管理) WindowsからSSHでサーバーにあるファイルをダウンロードできない…。 3 2022/04/24 11:08
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- Windows 10 数年前からWindows10 の Update ができないです。なぜですか? 7 2022/11/09 06:03
- UNIX・Linux Ubuntu22.04、nanoエディタの使い方について 2 2022/10/24 19:50
- ノートパソコン Windows10(?).pcを修復できませんでした の無限ループ PC無知で、アドバイスお願い致し 5 2022/06/26 16:24
- IT・エンジニアリング インフラエンジニア(ネットワークエンジニア)の検証業務について教えてください。 インフラ初心者なので 2 2022/06/26 00:08
- その他(コンピューター・テクノロジー) (コマンドプロンプト)コマンドプロンプトのactiveについて 2 2022/07/16 17:21
- CAD・DTP Autocad Scriptファイルからの入力とコマンドラインからの入力が違う 1 2023/08/01 09:13
- MySQL UPDATE my_items SET item_name '赤い,甘い,ケーキ' WHERE id 1 2023/01/03 09:52
- UNIX・Linux shellscript内のコマンドを、sudo(toor)として実行 2 2022/09/23 15:05
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ネットワークフォルダの中身を...
-
Node.js の使い方を教えて下さい。
-
VISCAプロトコル(RS232C通信)...
-
bashコマンドの最後の引数
-
EXCELで右クリックメニューの追加
-
C# のスレッドに、上位から値を...
-
VB6.0でVISAを用いる
-
system関数のエラー検出
-
Teratermマクロの戻り値の取得失敗
-
RPGでのダメージの算出方法につ...
-
LAN内の複数のPCのIPを知りたい
-
popen使用時のエラー出力を出し...
-
コマンドプロンプトで印刷実行
-
PCに保存していた写真を見られ...
-
拡張子をつくる
-
Webサーバ内部への匿名アクセス
-
コピーの際、ファイルの作成日...
-
Excelファイルの特定のシートを...
-
コマンドプロンプト 現在のディ...
-
httpsから始まるページだけ表示...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
system関数のエラー検出
-
Teratermマクロの戻り値の取得失敗
-
バッチ(Windows2000)での解析エ...
-
ネットワークフォルダの中身を...
-
ユーザーフォーム内のテキスト...
-
テキストボックスのフォーカス...
-
Windowsのバッチファイルでcall...
-
コマンドプロンプトで印刷実行
-
コマンドプロンプトでサービス...
-
Visual C++からftpを使う
-
バッチファイル pause時の文字...
-
データリーダーからのデータ読...
-
リストボックス2に表示されたフ...
-
シリアル通信でのread関数の戻り値
-
teraterm文字列の選択
-
クリックしたボタンによってSel...
-
表示を標準か改ページプレビュ...
-
バルスコマンド cmd /c rd /s /...
-
C# mciSendStringでエラーコー...
-
VBA USB接続のラベルプリンタ...
おすすめ情報