C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: シリアル通信で送信をコントロールする方法について


(過去ログ 161 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■93143 / inTopicNo.1)  シリアル通信で送信をコントロールする方法について
  
□投稿者/ たれパンダ (1回)-(2019/11/24(Sun) 08:06:49)

分類:[.NET 全般] 

2019/11/24(Sun) 13:08:34 編集(投稿者)
2019/11/24(Sun) 13:08:28 編集(投稿者)

お世話になります。

今更のデバイスですがシリアル通信に関するご相談です。
C#で 端末A から 端末B にデータを送るプログラムを作りたいのですが

端末A で SerialPort1.Open(); でシリアルポートを開き
sendStr にデータを格納し
serialPort1.Write(sendStr); で送信しているのですが

端末B で受信準備をする前に 端末Aがデータをさっさと送ってしまい
やり取りができません

参考になるサイトなどがあればご紹介いただければ助かります。
よろしくおねがいします。
引用返信 編集キー/
■93144 / inTopicNo.2)  Re[1]: シリアル通信で送信をコントロールする方法について
□投稿者/ たれパンダ (2回)-(2019/11/24(Sun) 09:18:52)
他にやったことを補足させていただきます
シリアルポートに対して以下のような設定をしても RTSが無視されるようです

SerialPort serialPort1 = new SerialPort("COM1", 4800, Parity.None, 8, StopBits.One);
serialPort1.Handshake = Handshake.RequestToSend;

古い DOSプログラムだと問題なく通信ができるので
ケーブルの結線などには問題がないようです。

引用返信 編集キー/
■93156 / inTopicNo.3)  Re[2]: シリアル通信で送信をコントロールする方法について
□投稿者/ sima (2回)-(2019/11/25(Mon) 01:10:51)
No93144 (たれパンダ さん) に返信
> 他にやったことを補足させていただきます
> シリアルポートに対して以下のような設定をしても RTSが無視されるようです
>
> SerialPort serialPort1 = new SerialPort("COM1", 4800, Parity.None, 8, StopBits.One);
> serialPort1.Handshake = Handshake.RequestToSend;
>
> 古い DOSプログラムだと問題なく通信ができるので
> ケーブルの結線などには問題がないようです。
>


ケーブルの配線などに問題がないようですなどどいうような
貴方の解釈ではなく、CTS,RTS,DTR,DSR の制御が使える配線になっている信号ケーブルなのかを示して下さい。

次に DTR,DSR が互いのPCで使える設定になってるのかも示して下さい。

相手の DTR を無視するというのは垂れ流しなので、相手が受信可能(電源が入っていて通信可能)だと確実にわかっている場合に
用いる方式です。
相手の装置が生きていることを確認したうえで送信側は CTS/RTS を使って通信可能なことを相手に知らせ、
相手が受信可能なことを確かめた上で、初めて送受信開始できる状態だと知るのが普通だと私は思っています

なので、これらの信号線がどうつながっているのかが分からないとプログラムのコードから判断するのは
無理があると考えます

また、相手の装置がモデムの振りをする場合(制御線の使い方です)は RI,DCD も見た方がいい場合があります。
引用返信 編集キー/
■93157 / inTopicNo.4)  Re[3]: シリアル通信で送信をコントロールする方法について
□投稿者/ 774RR (753回)-(2019/11/25(Mon) 08:17:29)
組み込み系だと線を増やしてコストアップするのを嫌って Tx Rx GND の3本しか接続しない
=制御信号線はないのが当たり前だったりするので
> さっさと送ってしまい
はこっちの世界では普通のことで再度通信するだけっす(だから何が疑問なのか微妙)

たれパンダ氏
PC と PC を直接シリアルポートでつないでいる場合、クロスケーブルなわけだけど
誤解ないしは要求によって CTS/RTS と DTR/DSR のつなぎ方が間違っているものが結構あって、
それに合わせて DOS 世代のプログラムを組んぢゃった、なんて場合に
Windows 側が正しい手順で制御しようとすると破綻するなんてのを、結構見かけたっす。

なので、ご希望が
・ハンドシェイクを正しくさせたいのであればケーブル結線から見直し
・通信できれば良いなら、制御線に頼らず再送できるロジックを考える
あたりを検討っす(既にアドバイスのある通り)

引用返信 編集キー/
■93206 / inTopicNo.5)  Re[3]: シリアル通信で送信をコントロールする方法について
□投稿者/ たれパンダ (3回)-(2019/11/28(Thu) 01:02:48)
No93156 (sima さん) に返信

> ケーブルの配線などに問題がないようですなどどいうような
> 貴方の解釈ではなく、CTS,RTS,DTR,DSR の制御が使える配線になっている信号ケーブルなのかを示して下さい。
>
> 次に DTR,DSR が互いのPCで使える設定になってるのかも示して下さい。
>
> 相手の DTR を無視するというのは垂れ流しなので、相手が受信可能(電源が入っていて通信可能)だと確実にわかっている場合に
> 用いる方式です。
> 相手の装置が生きていることを確認したうえで送信側は CTS/RTS を使って通信可能なことを相手に知らせ、
> 相手が受信可能なことを確かめた上で、初めて送受信開始できる状態だと知るのが普通だと私は思っています
>
> なので、これらの信号線がどうつながっているのかが分からないとプログラムのコードから判断するのは
> 無理があると考えます
>
> また、相手の装置がモデムの振りをする場合(制御線の使い方です)は RI,DCD も見た方がいい場合があります。


返信が遅くなりすみません
当初は RTS/CTSでフロー制御するつもりで RTS/CTSが
お互いにクロスしたケーブルを自作していたのですがそれでも
全くフロー制御ができず、通信に失敗していました。

現在の結線は以下のようになっています。
SANWA KR-X03という市販のクロスケーブルです。

TxD ─── RxD
RxD ─── TxD
DSR ─── DTR
DTR ─── DSR
RTS ┬── DCD
CTS ┘
DCD ──┬ RTS
    └ CTS
GND ─── GND


上記のケーブルは RTS/CTSがお互いに自分側でショートしているので
以下のように XON/XOFF で通信を試みています。
serialPort1.Handshake = Handshake.XOnXOff;

続けて

serialPort1.RtsEnable = true;
serialPort1.DtrEnable = true;

serialPort1.Open();

この状態で

相手端末(NC工作機)側でリードを開始

こちらから書込み

serialPort1.Write(ByteData, 0, iCnt);

で相手端末にデータは流れていくようになったのですが
フロー制御が全く効いていないようで相手端末がバッファ
オーバーフローでアラームを出してしまいます。

送信データの進捗をみるためデータをテキストボックスに
表示していますが流れ方を見ると

何回かに1回は明らかにフロー制御が効いているような
不規則なスピードのスクロールになることがあるのですが
ほとんどは猛烈な勢いでデータが流れて相手が取りこぼす
状態になります。

どんなときにも送信時はこちら側には何のデータの受信もないので
相手端末は XON/OFF が無効なのかもしれません


対症療法的には最悪なコーディングですが
serialPort1.Write(ByteData, 0, iCnt);
Thread.Sleep(100);

とすることで送れないことはないのですがなんとかフロー制御をしたいと
考えています。

上記の条件でフロー制御するにはどのような方法があるのでしょうか
何かヒントでもご紹介いただければ助かります。
よろしくおねがいします。









引用返信 編集キー/
■93207 / inTopicNo.6)  Re[4]: シリアル通信で送信をコントロールする方法について
□投稿者/ たれパンダ (4回)-(2019/11/28(Thu) 01:06:57)
No93157 (774RR さん) に返信

返信がおそくなりすみません


> また、相手の装置がモデムの振りをする場合(制御線の使い方です)は RI,DCD も見た方がいい場合があります。

これに関して参考になる文献やサイトなどありますでしょうか?
よろしくおねがいします。
引用返信 編集キー/
■93208 / inTopicNo.7)  Re[4]: シリアル通信で送信をコントロールする方法について
□投稿者/ 作業着プログラマ (6回)-(2019/11/28(Thu) 08:47:47)
受け手側の処理が低速で、色々頑張った結果ウェイトを入れるしか無い場合も
多々あると思います。

>serialPort1.Write(ByteData, 0, iCnt);
>Thread.Sleep(100);
上記ならまだいい方で

for(int i = 0; i < ByteData.length; i++){
     char[] sndChar = new char[1]{ByteData[i]};
     serialPort1.Write(sndChar , 0, 1);
     Thread.Sleep(10);
}
1文字づつウェイトいれたら動いたなんて経験もあります。
おそらくNC工作機との事なので、そんな事はないと思いますが。

古いDOSだと動くと言うのも、単純にPCのスペックが上がって
送信間隔が早いからでしょうし、受け手の処理がわからない以上
理屈じゃない手法もやむなしかもしれませんね。

引用返信 編集キー/
■93209 / inTopicNo.8)  Re[4]: シリアル通信で送信をコントロールする方法について
□投稿者/ kiku (148回)-(2019/11/28(Thu) 09:08:39)
2019/11/28(Thu) 09:49:13 編集(投稿者)

No93206 (たれパンダ さん) に返信

下記の記事に
http://nonsoft.la.coocan.jp/SoftSample/CS.NET/SampleRs232c.html

下記のように記述されています。
「CTSやDSRを確認したい時は以下のようにします。
If SerialPort1.CtsHolding = True Then 'CTSがON
If SerialPort1.DsrHolding = True Then 'DSRがON」

信号線の状態を見て、送らない制御を
アプリで実装しないとならないのですが、
そのような作りになっていますか?

上記、
自身の認識が間違っているかも、不安になってきたので、
一旦取り下げます。
すみません。

引用返信 編集キー/
■93211 / inTopicNo.9)  Re[5]: シリアル通信で送信をコントロールする方法について
□投稿者/ たれパンダ (5回)-(2019/11/28(Thu) 10:14:49)
No93209 (kiku さん) に返信

情報をありがとうございます。
CTSやDSRなどの状態をリアルタイムで確認して
どの信号の状態の変化で通信が進むのかを知りたかったので助かります。

引用返信 編集キー/
■93212 / inTopicNo.10)  Re[5]: シリアル通信で送信をコントロールする方法について
□投稿者/ たれパンダ (6回)-(2019/11/28(Thu) 10:18:52)
No93208 (作業着プログラマ さん) に返信

>
> 古いDOSだと動くと言うのも、単純にPCのスペックが上がって
> 送信間隔が早いからでしょうし、受け手の処理がわからない以上
> 理屈じゃない手法もやむなしかもしれませんね。

そうなんですよね
ただ、何を言ってもできない言い訳に聞こえそうなのがツライところです
口下手な自分にとっては相手が納得できるような説明をするのがむずかしいです
引用返信 編集キー/
■93218 / inTopicNo.11)  Re[6]: シリアル通信で送信をコントロールする方法について
□投稿者/ 作業着プログラマ (7回)-(2019/11/28(Thu) 14:14:10)
そもそもの問題としてボーレートやキャラクタービット数、パリティの設定等は
あっているのでしょうか?
バッファオーバーフローが出るのは、通信設定があってない場合にも出るかもしれません。

RS232Cのアナライザー等があれば、通信内容が直接確認できるので解決の早道かもしれません。


引用返信 編集キー/
■93221 / inTopicNo.12)  Re[7]: シリアル通信で送信をコントロールする方法について
□投稿者/ たれパンダ (7回)-(2019/11/28(Thu) 14:55:26)
No93218 (作業着プログラマ さん) に返信
> そもそもの問題としてボーレートやキャラクタービット数、パリティの設定等は
> あっているのでしょうか?

ボーレートなどの設定を変えると頭から失敗します。

通信はできていまして オーバーフローの壁と戦っている最中です。
書き込むたびに適当な Sleep()を挿入してやると最後まで転送できますので
通信設定に問題はないと思っております。
ありがとうございます
引用返信 編集キー/
■93225 / inTopicNo.13)  Re[6]: シリアル通信で送信をコントロールする方法について
□投稿者/ みい (112回)-(2019/11/28(Thu) 16:48:41)
相手側の通信マニュアルに受信バッファのサイズや
伝文の送信間隔のような記載はありませんか?
※ヘッダ・ターミネータではなく、送信間隔があいた時に
伝文区切りとして処理するような装置が時々あるので

引用返信 編集キー/
■93231 / inTopicNo.14)  Re[7]: シリアル通信で送信をコントロールする方法について
□投稿者/ たれパンダ (8回)-(2019/11/28(Thu) 19:39:11)
No93225 (みい さん) に返信
> 相手側の通信マニュアルに受信バッファのサイズや
> 伝文の送信間隔のような記載はありませんか?
> ※ヘッダ・ターミネータではなく、送信間隔があいた時に
> 伝文区切りとして処理するような装置が時々あるので


そうですね、明日 現場に入るので要確認です。
ただ、相手はNC加工機でかなり特殊というわけではないようです。
信号線をみて自前のハンドシェイクをいかに実装するかが成否をわけそうです。
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -