とあるデバイスを使う(その1)

概要

 しばらく検討出来なくなりますので、途中ですが状況を投稿しておきます。少し時間が経つと、何がどこにあるかもすっかり忘れてしまいますので、とりあえず自分用の手がかりとして残しておきます。
 下の図はRS232C通信でとあるデバイスを使って、データを取得しているフォーム(C#)状態です。正確に受信できていないケースもありますが、いつか修正したいと思います。
 後半にはARDUINOでの取得例について記載します。

プログラム(C#)

 未来の自分の為にプログラムを残します。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace UTR_S201_COM_TEST01
{
    public partial class Form1 : Form
    {
        string[] ports;
        public string strReceive;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e) {
            ports = SerialPort.GetPortNames();

            for (int ii = 0; ii < ports.GetLength(0); ii++) {
                comboBox1.Items.Add(ports[ii]);
            }

            comboBox1.SelectedIndex = ports.GetLength(0) - 1;

            if (serialPort1.IsOpen) { serialPort1.Close(); }

            button2.BackColor = Color.Silver;
        }

        // COMポート開く
        private void button2_Click(object sender, EventArgs e) {
            string p_name = comboBox1.Text.Trim();
            com_open(p_name);
        }

        //com_open
        private void com_open(string p_name) {
            if (serialPort1.IsOpen) {
                serialPort1.Close();
                button2.BackColor = Color.Silver;
                return;
            }

            serialPort1.PortName = p_name;
            serialPort1.BaudRate = 115200;     //, //変調回数(1秒あたり)
            serialPort1.Parity = Parity.None;
            serialPort1.DataBits = 8;           // 1変調あたりのbit数
            serialPort1.StopBits = StopBits.One;
            serialPort1.NewLine = "\r";
            serialPort1.ReadTimeout = 1000;
            serialPort1.WriteTimeout = 1000;
            //serialPort1.Handshake = Handshake.None;
            //serialPort1.DtrEnable = false;
            //serialPort1.RtsEnable = false;


            //serialPort1.DataReceived += serialPort_DataReceived;  // データ受信イベント

            serialPort1.Open();

            button2.BackColor = Color.Yellow;

        }

        // フォーム閉じる
        private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
            if (serialPort1.IsOpen) { serialPort1.Close(); }
        }

        // データ送信ボタン
        private void button1_Click(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen) {
                MessageBox.Show("ポートが閉じています。", "ポート閉");
                return;
            }

            int cmd_n = int.Parse(textBox2.Text.Trim());
            SerialPort_DataSend(cmd_n);

            cmd_n ++ ;
            if (cmd_n > 5) { 
                cmd_n = 0;
            }

            this.textBox2.Text = cmd_n.ToString();
        }

        // データ送信
        private void SerialPort_DataSend(int cmd_no) {
            byte[] s_Data = std.S201_CMD[cmd_no];

            int byt_l = s_Data.Length;
            int chk_e = s_Data[byt_l - 1];
            int cmd_sum = 0;

            if (chk_e != 3) { return; }

            byte[] tr_dt = new byte[byt_l + 2];

            for (int ii = 0; ii < byt_l; ii++) {
                tr_dt[ii] = s_Data[ii];
                cmd_sum += s_Data[ii];
            }

            tr_dt[byt_l] = (byte)(0xFF & cmd_sum);
            tr_dt[byt_l + 1] = 0x0d;

            serialPort1.Write(tr_dt, 0, byt_l + 2);
        }

        // ■■■ 参考1によるデータ受信 ■■■
        // シリアルポート データ受信イベント
        // [ com_open ] 内で定義必要 → serialPort1.DataReceived += serialPort_DataReceived;
        private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e){

            SerialPort seriPort = (SerialPort)sender;

            int readByteS = seriPort.BytesToRead;           // 受信データ長取得

            if (readByteS > 0) {
                byte[] buff = new byte[readByteS];
                seriPort.Read(buff,0,readByteS);

                strReceive = "";

                for (int i = 0; i < buff.Length; i++) { 
                    strReceive += string.Format("{0:X2}", buff[i]) ;
                    strReceive += " " ;
                }

                strReceive = strReceive.Trim() ;
                serialPort1.DiscardInBuffer();              // 入力バッファークリア

                if (this.InvokeRequired) {
                    this.Invoke(new Action(this.UpdateText));
                } else {
                    this.textBox1.Text += strReceive + Environment.NewLine;
                }
            }
        }

        // 受信データ表示
        private void UpdateText() {
            textBox1.AppendText(strReceive);

            string l_str = strReceive.Substring(strReceive.Length - 2);
            if (l_str == "0D") { textBox1.AppendText(Environment.NewLine); }
        }

        // ■■■ 参考2によるデータ受信 ■■■
        private delegate void Delegate_RcvDataToTextBox(string data); 

        // データ受信イベント
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort seriPort = (SerialPort)sender;

            int readByteS = seriPort.BytesToRead;           // 受信データ長取得

            if (readByteS > 0)
            {
                byte[] buff = new byte[readByteS];
                seriPort.Read(buff, 0, readByteS);

                strReceive = "";

                for (int i = 0; i < buff.Length; i++)
                {
                    strReceive += string.Format("{0:X2}", buff[i]);
                    strReceive += " ";
                }

                string data = strReceive.Trim();
                //serialPort1.DiscardInBuffer();              // 入力バッファークリア

                if (this.InvokeRequired){
                    Invoke(new Delegate_RcvDataToTextBox(RcvDataToTextBox), new Object[] { data });
                } else {
                    this.textBox1.Text += strReceive + Environment.NewLine;
                }
            }
        }

        //受信データをテキストボックスに設定する
        private void RcvDataToTextBox(string data) {
            if (data != null) {
                string d_trim = data.Trim();
                string l_str = d_trim.Substring(d_trim.Length - 2);

                if (l_str == "0D"){
                    textBox1.AppendText(d_trim);
                    textBox1.AppendText(Environment.NewLine);
                } else {
                    textBox1.AppendText(data);
                }
            }
        }

    }
}



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UTR_S201_COM_TEST01
{
    public static class std
    {
        public static byte[][] S201_CMD = new byte[][] {
            new byte[]{ 0x02, 0x00, 0x4F, 0x01, 0x00, 0x03 } ,                                                              
            new byte[]{ 0x02, 0x00, 0x4F, 0x01, 0x90, 0x03 } ,                                                              
            new byte[]{ 0x02, 0x00, 0x4E, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03 } ,                          
            new byte[]{ 0x02, 0x00, 0x55, 0x02, 0x41, 0x01, 0x03 } ,                                                        
            new byte[]{ 0x02, 0x00, 0x55, 0x0B, 0x31, 0x01, 0x1F, 0xCE, 0x81, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03 } ,  
            new byte[]{ 0x02, 0x00, 0x4E, 0x07, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 } ,                          
            new byte[]{ 0x02, 0x00, 0x4E, 0x07, 0x00, 0x65, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03 }                            
    }
}

ARDUINO受信例

配線接続

ARDUINOプログラム

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);          // RX,TXの割り当て

// 設定コマンド
uint8_t CMD[6][18]={
      { 0x02,0x00,0x4F,0x01,0x00,0x03,0x55,0x0D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF },
      { 0x02,0x00,0x4F,0x01,0x90,0x03,0xE5,0x0D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF } ,
      { 0x02,0x00,0x4E,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x5A,0x0D,0xFF,0xFF,0xFF,0xFF } ,
      { 0x02,0x00,0x55,0x02,0x41,0x01,0x03,0x9E,0x0D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF } ,
      { 0x02,0x00,0x55,0x0B,0x31,0x01,0x1F,0xCE,0x81,0x02,0x00,0x00,0x00,0x00,0x02,0x03,0x09,0x0D } ,
      { 0x02,0x00,0x4E,0x07,0x00,0x65,0x00,0x00,0x00,0x00,0x00,0x03,0xBF,0x0D,0xFF,0xFF,0xFF,0xFF } ,      
  };
     
// 初期設定
void setup() {
  Serial.begin(115200);                    // シリアルモニタ出力
  mySerial.begin(115200);                   // ソフトウェアシリアル通信開始

  int cn_fct = sizeof(CMD[0]) ;
  int cn_cmd = sizeof(CMD) / cn_fct ;

  uint8_t buf_tmp[ cn_fct ] ;

  for(int i = 0 ; i < cn_cmd ; ++i ){
    for(int j = 0 ; j < cn_fct ; ++j ){ buf_tmp[j] = CMD[i][j];}
 
    // コマンド送信
    send_cmd_S201( buf_tmp , cn_fct );
    delay(1);
  
    // データ受信
    String rcvDat=""; 
    while(mySerial.available() > 0){
      int val = mySerial.read() ;
      String str = "00" + String(val , HEX);
      str = str.substring(str.length() - 2) + " " ;
      rcvDat += str;

      if(val==13){
        Serial.println(rcvDat);
        break;
      }
    }
    //if(i>=1){ break; }
    delay(300);
  }
  Serial.println("");
  Serial.println("START!");
}

// ■メイン処理■
void loop() {
  // データ受信
  String rcvDat="";
  uint8_t rBuf[26];
  int rcv_cn = 0;
  int sum_ck = 0;
  
  while(mySerial.available() > 0){
    int val = mySerial.read() ;
    if(rcv_cn < 26){ rBuf[rcv_cn] = val; }
    if(rcv_cn < 24){ sum_ck += val; }
      
    String str = "00" + String(val , HEX);
    str = str.substring(str.length() - 2) + " " ;
    rcvDat += str;
    rcv_cn++;

    if(val==13){
      if(rcv_cn == 26){
        sum_ck = sum_ck & 0xFF ;
        if(rBuf[0]==2 && rBuf[23]==3 && rBuf[24]==sum_ck){
          Serial.println(rcvDat);
        }
      }
      break;
    }
  }
}


// データ送信
void send_cmd_S201(uint8_t * buf , int sz_bf){
   for(int i = 0 ; i < sz_bf ; ++i ){
    String str = "00" + String(buf[i] , HEX);
    str = str.substring(str.length() - 2) ;
    Serial.print(str);
    Serial.print(" ");
    mySerial.write(buf[i]);
    if(buf[i]==0x0D || buf[i]==0xFF){ break; }
  }
  Serial.println("");
  delay(100);
}

まとめ

 いつか自分の役に立つことを願っています。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です