visualStudio2017 でシリアル通信で相手ポートに送信したデータの内容に依って、対応した受信データを受け取る処理を作っています。
(実際はRS232Cで複数接続したセンサに命令を送って返答を非同期で受け取るシステムのです。)
例えば10台センサがあるとして、10回命令を送信します。(測定値を送るというコマンドなど)
すると、10台分の結果を随時受け取り、変数にセットする仕組みです。
センサ側はCOMポートで接続しています。
受信はSerialPortのDataReceivedイベントを使っており、データを受け取る所は確認したのですが、この情報を
上位クラスが持っている変数にセットしたいのです。
送信データを10台文loopしているメソッドで受信データを受け取り、変数に値をセットするというのは可能なのでしょうか。
C#
1PressSerial.cs 2 3 // グループNo 4 public int GroupNo { private set; get; } 5 private Serial mSerial; 6 delegate void DisplayTextDelegate(); 7 8 public PressSerial(int group) 9 { 10 GroupNo = group; 11 12 mSerial = new Serial(SerialEventHandler); 13 14 } 15 16 /// シリアル通信クラス コンストラクタ 17 public PressSerial() 18 { 19 20 mSerial = new Serial(SerialEventHandler); 21 22 } 23 24 public async Task Hell_Async(int gno, int ch_su,List<PressSensInfo> psenList) 25 { 26 //psenListに10台文の情報が入っている 27 var timeout = TimeSpan.FromMilliseconds(1000); 28 for (int i = 0; i < ch_su; i++) 29 { 30 var rc = await Task.WhenAny( 31 Task.Run(async () => 32 { 33 // 送信コマンドの編集を行って送信 34 CreateSendCommand(psens.Channel); 35 })); 36 37 try 38 { 39 rc.Wait(timeout); 40 sensInfo.Add(new PressSerial(gno, i)); 41 } catch 42 { 43 44 } 45 } 46 } 47 public void CreateSendCommand(int ch) 48 { 49 50 byte[] Packet; 51…ここで送信データ文字列をbyte型に変換処理などを行っている 52 mSerial.SendBuff(Packet); 53 } 54 55 void SerialEventHandler(Serial.SerialEventArgs e) 56 { 57 switch (e.Event) 58 { 59 case Serial.SerialEventArgs.SERIALEVENT.SERIALEVENT_CONNECT: 60 break; 61 case Serial.SerialEventArgs.SERIALEVENT.SERIALEVENT_RECEIVE: 62 /// <summary> 63 /// 受信コマンド 64 /// </summary> 65 void CommandReceive() 66 { 67 68 string text = System.Text.Encoding.ASCII.GetString(e.ReceiveBody); 69 tmpReceivedByte = e.ReceiveBody; // ここに受信データ 70 71 72 } 73 DisplayTextDelegate d = new DisplayTextDelegate(CommandReceive); 74 d?.Invoke(); 75 76 break; 77 } 78 } 79
C#
1Serial.cs 2 public event SerialEventHandler SerialEvent;// Serialデリゲート 3 public delegate void SerialEventHandler(SerialEventArgs e);// イベントハンドラのデリゲート 4 5 public void SendBuff(byte[]sendBuffer) 6 { 7 byte[] rbuf = new byte[1]; 8 if (m_Serial.IsOpen == true) 9 { 10 // 1バイトずつ送信 11 for (int c = 0; c < sendBuffer.Length; c++) 12 { 13 rbuf[0] = sendBuffer[c]; 14 m_Serial.Write(rbuf, 0, rbuf.Length); 15 } 16 } 17 } 18 19 private void Serial_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 20 { 21 byte tbyte = 0; 22 // 受信バッファから値を取得する 23 tbyte = (byte)m_Serial.BytesToRead; 24 25 byte[] rbuf = new byte[tbyte]; 26 27 m_Serial.Read(rbuf, 0, tbyte); 28 29 //受信イベント 30 ReceiveEvent(SerialEventArgs.SERIALEVENT.SERIALEVENT_RECEIVE, rbuf); 31 } 32 33 /// 受信デリゲート呼び出し処理 34 private void ReceiveEvent(SerialEventArgs.SERIALEVENT e, byte[] body) 35 { 36 //デリゲート呼び出し 37 SerialEvent?.Invoke(new SerialEventArgs(e, mNoticeId, body)); 38 } 39
C#
1PressureSens.cs(ユーザーがアクセスする最上位クラス) 2 // シリアル通信クラス。要素はグループ数分。 3 private List<PressSerial> PressSerialList; 4 // センサ情報リスト 5 public List<PressSensInfo> PSensInfoList { private set; get; } 6 7 // コンストラクタ 8 public PressureSens() 9 { 10 PressSerialList = new List<PressSerial>(); 11 PSensInfoList = new List<PressSensInfo>(); 12 for (int i = 0; i < 3) // グループNo(接続したCOMポート数)が3台とする 13 { 14 PressSerialList.Add(new PressSerial(i); 15 } 16 } 17 18 // センサ情報、接続台数チェックなど。 19 public async Task<Boolean> Initialize() 20 { 21 Boolean ret = true; 22 23 // センサ応答チェック呼び出し 24 await Task.Run(async () => 25 { 26 // 実際はグループ毎に非同期で計測する。 27 28 int gno = 3; // グループNo(接続したCOMポート数) 29 int ch_su = 10; // 接続台数 30 for (int i = 0; i < gno; i++) 31 { 32 var rc = mPressSerial.Hell_Async(i, ch_su, PSensInfoList); 33 } 34 } 35 }); 36 return true; 37 } 38
C#
1 PressSensInfo.cs(センサデータ格納クラス) 2 /// 現在時刻(アラームやセンサ値など状態更新時の時刻) 3 public DateTime Time; 4 /// グループNo 5 public int GroupNo { private set; get; } 6 /// センサチャンネル 7 public int c { private set; get; } 8 /// グローバルID 9 /// </summary> 10 public int GlobalID { private set; get; } 11 /// センサ計測値 12 public Double Value = 0.0; 13 /// <summary> 14 /// センサ状態 15 /// </summary> 16 public int Status { private set; get; } = 0; // 0:待機 1:計測中 2:データエラー 3: …など 17 18 // センサデータクラスのコンストラクタ 19 public PressSensInfo (int group, int ch) 20 { 21 Status = 0; 22 Time = DateTime.Now; 23 GroupNo = group; 24 Channel = ch; 25 GlobalID = group * 100 + ch; 26 } 27
PressSerialクラスのHell_Asyncメソッド内でList配列のセンサ情報をloopでID情報などを送信して、センサ側からの応答を[受け取り、同じ配列データの変数に受信内容をセットするようにしたいのですが、DataReceivedイベントから、デリゲード呼び出しでPressSerialクラスのSerialEventHandler内で受信データを拾うことはできたのですが、この値をどうやってList<PressSensInfo>内にセットすれば良いか、
SerialEventHandlerから上位のメソッドにコールバックする方法が分かりません。
上に[書いたメソッドは直接関係ないところは省略しています。
どうか、宜しくお願いいします。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/06/27 03:00