中堅プログラマーの備忘録

忘れっぽくなってきたので備忘録として・・・

【C#.net】RS232Cで【制御文字(STX、ETX)】を送るにはどうしたらいいのか?

1.概要

RS232C通信を行う時、文字列であれば【serialPort1.Write】または【serialPort1.WriteLine】に
送信したい文字列を突っ込めば、送信することは出来ますが
送信したいデータの中に【STX】【ETX】等の【制御文字】が含まれていた場合
文字列を使った送信方法は簡単には出来ません。
ではどのようにするかというと16進コードにしてbyte型にて送ることになります。

2.16進コードをbyte型配列にする

例えば送信したいデータが
【STX】【A】【ETX】
だったとします。

これを16進コードに変換すると
【0x02】【0x41】【0x03】
になります。

これをbyte型配列に変換し
【serialPort1.Write】
で送るという形になります。

以下、変換用スクリプトです。

string str = "02-41-03";
var tmp = str.Split('-').Select(hex => Convert.ToByte(hex, 16));
byte[] sendData = tmp.ToArray();

3.byte型配列を送る

byte型配列を送信するには
【serialPort1.Write】
で送信します。

serialPort1.Write(sendData, 0, sendData.Length)

4.スクリプト

アプリ起動時にbyte型配列のデータを送信し
データを受信したらメッセージボックスで表示するようにしています。

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

namespace RS232Ctest
{
    public partial class Form1 : Form
    {
        string[] ports;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ports = SerialPort.GetPortNames();
            serialPort1.PortName = ports[0];
            serialPort1.BaudRate = 9600;
            serialPort1.DataBits = 8;
            serialPort1.StopBits = System.IO.Ports.StopBits.One;
            serialPort1.Parity = System.IO.Ports.Parity.None;
            try
            {
                if (serialPort1.IsOpen == true)
                {
                    return;
                }
                serialPort1.Open();
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            if (serialPort1.IsOpen == true)
            {
                try
                {
                    string str = "02-41-03";
                    var tmp = str.Split('-').Select(hex => Convert.ToByte(hex, 16));
                    byte[] sendData = tmp.ToArray();
                    serialPort1.Write(sendData, 0, sendData.Length);
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string strDataReceived = "";
            Byte[] buf = new byte[serialPort1.BytesToRead];
            try
            {
                serialPort1.Read(buf, 0, buf.Length);
                strDataReceived = BitConverter.ToString(buf);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            if(serialPort1.IsOpen == true)
            {
                serialPort1.Close();
                MessageBox.Show(strDataReceived);
            }
        }
    }
}

5.結果

今回も相手側に【serister】を使いました。
アプリケーション起動時に【0x02】【0x41】【0x03】を送っています。
f:id:tsu--kun:20191002165028p:plain


更に【serister】から
【0x02】【0x42】【0x03】を送った結果です。
f:id:tsu--kun:20191002165045p:plain


こちらの記事も参考に
www.chuken-engineer.com