SerialPortのクラス継承をしたい
SerialPortクラスとは、RS232CやUSBシリアル等でのデータのやり取りで使います。
独自の送受信処理を行ったりする事があると思います。
そうなると、フォームコントロールSerialPortを追加して、ソースコード(Form1.csとか)にダラダラと入力することになってしまいみっともない感じに。
そこで、SerialPortを継承した新しいクラスを作って、そこに独自の送受信処理を行うようにしてみたいと思います。
SerialPortに限らず、クラス継承についての参考にもなるかもしれません。
いつものSerialPortの使い方
その前に、まずはSerialPortの使い方を軽く解説しておきます。
1.Formエディタ画面で、SerialPortを追加
名前は「serialPort1」とします。
(ついでにボタンも追加しておきます。=button1)
2.Form1.csソースコード内
フォーム起動時のイベントと、ボタンクリック時のイベントを追加して、COM1に対して送受信する例になります。
// Form起動時
private void Form1_Load(object sender, EventArgs e)
{
// シリアルポート1
serialPort1.PortName = "COM1";
serialPort1.BaudRate = 9600;
serialPort1.Parity = System.IO.Ports.Parity.None;
serialPort1.DataBits = 8;
serialPort1.StopBits = System.IO.Ports.StopBits.One;
serialPort1.ReadTimeout = 3000; // 受信タイムアウト
serialPort1.Open();
}
// ボタンクリック時
private void button1_Click(object sender, EventArgs e)
{
// 独自フォーマットの送受信
serialPort1.WriteLine("hirakegoma"); // 送信
bool b = false;
try
{
string str;
StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
str = serialPort1.ReadLine(); // 受信
if (stringComparer.Equals("haiyo!\r", str))
{
b = true;
}
}
catch
{
// タイムアウト
}
}
// フォーム閉じるとき
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
serialPort1.Close();
}
メインフォームにごちゃごちゃ記載してしまうのはしょうがないところではあります。
次ではクラス継承させた例を紹介したいと思います。
SerialPortを継承したクラス例
1.クラス作成
クラス名は「clsCOM」とします。
clsCOM.csファイルが作成されます。
2.clsCOM.csソースコード内
class定義の後ろに「: SerialPort」を付けるとクラス継承されます。
今回の例では、オープン/クローズ/送信/受信関数を用意しました。
とりあえず、送信は”hirakegoma”の文字を送って、”haiyo!”の文字が返ってきたらOK(true)と判定してます。
using System;
using System.IO.Ports; // SerialPort
namespace WindowsFormsApplication1 // Form1.csのnamespaceと同じ名前に
{
internal class clsCOM : SerialPort // 適当な名前に。SerialPort継承
{
public clsCOM(string port, int baud, System.IO.Ports.Parity parity, int databit, System.IO.Ports.StopBits stopBits)
{
this.PortName = port;
this.BaudRate = baud;
this.Parity = parity;
this.DataBits = databit;
this.StopBits = stopBits;
this.ReadTimeout = 3000; // 受信タイムアウト
// 受信イベント登録
//this.DataReceived += new SerialDataReceivedEventHandler(clsCOM_DataReceived);
}
public bool openCOM()
{
bool b = false;
try
{
this.Open();
b = true;
}
catch
{
}
return b;
}
public void closeCOM()
{
this.Close();
}
public void sendCOM()
{
// 独自フォーマットで送信など
this.WriteLine("hirakegoma");
}
public bool recvCOM()
{
bool b = false;
try
{
string str;
StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
str = this.ReadLine();
// 独自フォーマット受信など
if (stringComparer.Equals("haiyo!\r", str))
{
b = true;
}
}
catch
{
// タイムアウト
}
return b;
}
//private void clsCOM_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
//{
// SerialPort sp = (SerialPort)sender;
// string indata = sp.ReadExisting();
// Console.WriteLine("Data Received:");
// Console.Write(indata);
// // 受信後処理を実施
// // ~
//}
}
}
3.Form1.csソースコード内
フォーム内では、上記クラスを使う例になります。
以下例の動きは、送信したら、すぐ受信待ちするようにしてます。
private clsCOM m_cls;
private void Form1_Load(object sender, EventArgs e)
{
m_cls = new clsCOM("COM1", 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
m_cls.openCOM();
}
private void button1_Click(object sender, EventArgs e)
{
m_cls.sendCOM(); // 送信処理
bool b = m_cls.recvCOM(); // 受信処理
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
m_cls.Close();
}
ふぅ、なんかすっきり。
ちなみに、前述のフォームコントロール「serialPort1」は使っておりませんので不要です。
最後に
継承クラスを作る前と後のフォーム「Form1.cs」を比べてみると、なんかすっきり。
動きとしてはどちらも同じになります。
しょせんは見た目の違いだけで好みが分かれるところではありますが、例えば複数チームで分散開発したいときなんかでも、同じようにクラス継承して開発することがあるかもしれませんね。
ご参考になれば幸いです。
最後まで見てくれてありがとう