在工業自動化領域,上位機(PC)與可程式邏輯控制器(PLC)的序列通訊是經典需求。本文示範如何在 C# 專案中引用 ActiveX 元件 MSComm (Microsoft Communications Control 6.0),依據松下 FPΣ 系列 PLC 專用的 MEWTOCOL-COM 協定,實現資料讀寫與即時監控。
註冊 MSComm: 最簡單的方式是安裝 Visual Basic 6.0,安裝完成後 Mscomm32.ocx 會自動註冊至系統。隨後在 VS 工具箱右鍵選擇 Choose Items → COM Components,勾選 Microsoft Communications Control, version 6.0 即可拖曳至表單。
% (起始) + HL (站號) + #/$ (指令類型) + 指令內容 + BCC (校驗) + CR (結束)% 到指令內容結束的所有字元 ASCII 碼做 XOR 累積,取兩位十六進位字串。範例指令幀(讀 DM 區):%01#RDD0100601036
對應回應幀:%01$RDD0100601036[資料]BCC CR
using System;
using System.Text;
using System.Windows.Forms;
using MSCommLib; // 需參考 AxInterop.MSCommLib.dll
namespace PLC_Communication
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
axMSComm1.CommPort = 1; // COM1
axMSComm1.Settings = "9600,n,8,1"; // 鮑率,無奇偶校驗,8資料位,1停止位
axMSComm1.RThreshold = 1; // 收到 1 字元觸發 OnComm
axMSComm1.InputMode = InputModeConstants.comInputModeText;
}
private void btnSend_Click(object sender, EventArgs e)
{
if (!axMSComm1.PortOpen) axMSComm1.PortOpen = true;
axMSComm1.DTREnable = true;
axMSComm1.RTSEnable = true;
axMSComm1.InputLen = 0; // 清空接收緩衝區
string cmd = txtCommand.Text.Trim(); // 例:%01#RDD0100601036
string frame = cmd + CalculateBCC(cmd) + "\r"; // 加上 BCC 與 CR
axMSComm1.Output = frame;
// 簡易同步讀取(實務建議用 OnComm 事件非同步處理)
System.Threading.Thread.Sleep(100);
txtResponse.Text = axMSComm1.Input;
}
private void btnClose_Click(object sender, EventArgs e)
{
if (axMSComm1.PortOpen) axMSComm1.PortOpen = false;
Application.Exit();
}
/// 計算 MEWTOCOL-COM BCC (XOR 校驗)
private string CalculateBCC(string frame)
{
int bcc = 0;
// 從索引 1 開始(跳過起始符 '%')
for (int i = 1; i < frame.Length; i++)
bcc ^= frame[i];
return bcc.ToString("X2"); // 兩位大寫十六進位
}
}
}
axMSComm1.OnComm 事件處理接收資料,避免 UI 凍結。% 之後所有字元,不含結束符 CR。Mscomm32.ocx,或採用 .NET 原生 System.IO.Ports.SerialPort 類別替代(需自行實作協定封包/解包)。掌握基本通訊後,可進一步封裝 ReadDM、WriteDM、MonitorBit 等方法,結合定時器實現即時資料採集、趨勢圖繪製、警報記錄等 SCADA 雛形功能。