dodox86さん、coco_bauerさん、pepperleafさん ご指摘ありがとうございます。
追加情報を添付させていただきます。
PC⇔シーケンサをRS-232ケーブルで接続し、デバイス(本件ではM)を読みだそうとしています。
ハンドシェイクについて、Handshake.None(※0)~Handshake.RequestToSendXOnXOff(※3) まで、
全通り振ってみましたが、結果は変わりませんでした。
尚、問題なく送受信できるTeraTerm上の設定は、
以下の通りとなりWondowsFormアプリで設定した内容と同じと考えております。
ボーレート :115200
データ :8bit
パリティ :odd
ストップ(s):1bit
フロー制御 :none
C#のソースコードを添付します。
C#
1 ★シリアル通信設定→送信→受信読み込み部分 2 SerialPortContorl seriIns_plc = new SerialPortContorl(); 3 int ret = seriIns_plc.Open_plc("COM19"); ★シリアル通信設定 4 if (Program.DefinedValue.PORT_OPEN != ret) 5 { 6 /* Open失敗 */ 7 seriIns_plc.Close(); 8 seriIns_plc.Dispose(); 9 seriIns_plc = null; 10 return; 11 } 12 seriIns_plc.sendCmd_plc(); 13 for (;;) { 14 System.Threading.Thread.Sleep(1000); 15 Console.WriteLine("{0}", seriIns_plc.BytesToRead); ★ここで受信サイズを参照するも4しかでない 16 if (seriIns_plc.BytesToRead > 0) 17 { 18 byte data = (byte)seriIns_plc.ReadByte(); ★受信部分 19 Console.WriteLine("recv:{0}", data); 20 } 21 } 22 23 ★通信設定部分 24 public int Open_plc(string portName) 25 { 26 try 27 { 28 PortName = portName; 29 BaudRate = 115200; 30 DataBits = 8; 31 Parity = Parity.Odd; 32 StopBits = StopBits.One; 33 //Encoding = Encoding.UTF8; 34 //NewLine = "\r\n"; 35 36 Encoding = Encoding.GetEncoding("shift_jis"); 37 Handshake = Handshake.None; 38 39 Open(); 40 41 ret = Program.DefinedValue.PORT_OPEN; 42 } 43 catch 44 { 45 } 46 return 0; 47 } 48 49 //******************************************* 50 // MCプロトコル 51 //******************************************* 52 static public byte PLC_SEND_CTLCODE_ENQ = 0x05; 53 static public string PLC_SEND_FRAMENO_4C = "F8"; 54 static public string PLC_SEND_ADDRESSNO = "00"; 55 static public string PLC_SEND_NETWORKNO = "00"; 56 static public string PLC_SEND_PCNO = "FF"; 57 static public string PLC_SEND_UNITIO = "03FF"; 58 static public string PLC_SEND_UNITNO = "00"; 59 static public string PLC_SEND_UNITADR = "00"; 60 61 static public string PLC_SEND_READ_CMD = "0401"; 62 static public string PLC_SEND_SUB_CMD = "0000"; 63 static public string PLC_SEND_READ_DNO = "003062"; 64 static public string PLC_SEND_MCODE = "M*"; 65 66 ★データ送信部分 67 public void sendCmd_plc() 68 { 69 byte[] convByte = new byte[1024]; 70 byte[] sendByte = new byte[1024]; 71 StringBuilder sendStr = new StringBuilder(); 72 73 sendStr.Append(PLC_SEND_FRAMENO_4C); //F8 74 sendStr.Append(PLC_SEND_ADDRESSNO); //00 75 sendStr.Append(PLC_SEND_NETWORKNO); //00 76 sendStr.Append(PLC_SEND_PCNO); //FF 77 sendStr.Append(PLC_SEND_UNITIO); //03FF 78 sendStr.Append(PLC_SEND_UNITNO); //00 79 sendStr.Append(PLC_SEND_UNITADR); //00 80 sendStr.Append(PLC_SEND_READ_CMD); //0401 81 sendStr.Append(PLC_SEND_SUB_CMD); //0000 82 sendStr.Append(PLC_SEND_MCODE); //M* 83 sendStr.Append(PLC_SEND_READ_DNO); //003062 84 sendStr.Append("0005"); //デバイス点数(5点) 85 86 convByte = Encoding.UTF8.GetBytes(sendStr.ToString()); 87 byte chkSum = 0; 88 foreach(byte byteUnit in convByte) 89 { 90 chkSum += byteUnit; 91 } 92 byte[] chksum_4bit= { 0, 0 }; 93 chksum_4bit[0] = (byte)(chkSum >> 4); 94 chksum_4bit[1] = (byte)(chkSum & 0xF); 95 96 byte sendDataSize = 0; 97 sendByte[0] = PLC_SEND_CTLCODE_ENQ; 98 sendDataSize++; 99 foreach (var byteUnit in convByte.Select((value,idx) => new { value, idx })) 100 { 101 sendByte[1 + byteUnit.idx] = byteUnit.value; 102 sendDataSize++; 103 } 104 sendByte[sendDataSize] = btoa(chksum_4bit[0]); 105 sendDataSize++; 106 sendByte[sendDataSize] = btoa(chksum_4bit[1]); 107 sendDataSize++; 108 sendByte[sendDataSize] = 0x0D; 109 sendDataSize++; 110 sendByte[sendDataSize] = 0x0A; 111 sendDataSize++; 112 113 Write(sendByte, 0, sendDataSize); ★sendByteに格納されたデータをTeraTermから送信すると問題ない 114 }
問題事項
現在、デバイス(M3062)に対してシリアル通信(RS-232)にて一括読み出し操作を実施しているが、
応答データがいくら待っても4byteしか受信できない。
(BytesToReadをループでモニタし続けているが4byteから増えない)
尚、シーケンサとのデータ送受信はC#で組んだWindow From上で実施しているが、
このForm上から発行するデータ(要求伝文)をダンプしてTeraTerm上から発行すると
問題なくデータを受信できる。
このことからC#のプログラム上のシリアル通信設定周りに問題があるのではないかと
推測している。
ただ、原因となりそうな箇所が見受けられず困っている状況のため、
アドバイスをいただきたい。
送信データ(要求伝文)
0x05 = コントロールコード(ENQ)
0x46 0x38 = 4Cフレーム(F8)
0x30 0x30 = 局番号(00)
0x30 0x30 = ネットワーク番号(00)
0x46 0x46 = PC番号(FF)
0x30 0x33 0x46 0x46 =要求先ユニットI/O番号(03FF)
0x30 0x30 = 要求先ユニット局番号(00)
0x30 0x30 = 自局番号(00)
0x30 0x34 0x30 0x31 = コマンド(0401)
0x30 0x30 0x30 0x30 = サブコマンド(0000)
0x4d 0x2a = デバイスコード(M )
0x30 0x30 0x33 0x30 0x36 0x32 = デバイス番号(3062)
0x30 0x30 0x30 0x35 = デバイス点数(0005)
0x36 0x35 =チェックサム
0x0d 0x0a =コントロールコード(CR+LF)
受信データ
・Formアプリで受信(★問題発生時)
→0x02 0x46 0x38 0x30
★途中までしか受信できていない(4byteしかない)
・TeraTermで受信(★問題なし時)
02
46 38
30 30 30 30
46 46
30 33 46 46
30 30 30 30
30 30 30 30
30 30 30 30
30 30 38 30
30 30 30 30
30 30 30 30
03
34 34
0D 0A
使用環境情報
・製品名:シーケンサ(iQ-R ,Q,L,QnA,A)
・形名:Q00UJCPU(※三菱製)
・通信使用PC=Windows7(64bit)
・シーケンサCPU=Q00UJCPU
・通信方式=RS-232(MCプロトコル)
・MCプロトコル形式=形式4(ASCII)
・参照資料1(sh080001)
→QnUCPUユーザーズマニュアル(機能解説・プログラム基礎編)
・参照資料2(sh080003)
→MELSECコミュニケーションプロトコル リファレンスマニュアル
C#
1 シーケンサとのシリアル通信設定 2 public int Open_plc() 3 { 4 try 5 { 6 PortName = "COM19"; 7 BaudRate = 115200; 8 DataBits = 8; 9 Parity = Parity.Odd; 10 StopBits = StopBits.One; 11 12 Open(); 13 } 14 catch {} 15 return 0; 16 } 17 18
回答4件
あなたの回答
tips
プレビュー