--- tags: Serial Port, C# --- <!-- 使用黑色主題 --> {%hackmd BkVfcTxlQ %} <!-- 決定 CSS 樣板 --> {%hackmd @aidan/inc_hackmd_css %} # 在 Console 底下使用 SerialPort(1) * [GitHub](https://github.com/aidan0328/SerialTool_CSharp.git) * [Console 底下使用 SerialPort(2)](https://hackmd.io/@aidan/SerialPort-2_Console) ## <span class="Title">主題0. GetPortNames()</span> ### <span class="SubTitle">Lab0-1 取得本機的所有 COM Port 名稱</span> ```C#= using System; using System.IO.Ports; namespace SerialTool_CSharp { class Program { static void Main(string[] args) { string[] ports = SerialPort.GetPortNames(); foreach (string p in ports) { Console.WriteLine(p); } Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } } } ``` ## <span class="Title">主題1. 傳送</span> ### <span class="SubTitle">Lab1-1 傳送字串</span> ```C#= using System; using System.IO.Ports; namespace SerialTool_CSharp { public class Program { public static void Main() { SerialPort serialPort = new SerialPort("COM3", 115200); serialPort.Open(); serialPort.WriteLine($"From {serialPort.PortName}, Hello"); serialPort.Close(); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } } } ``` ### <span class="SubTitle">Lab1-2 來探討 static </span> <font color = "Red">以下程式是無法編譯</font> ```C#= using System; using System.IO.Ports; namespace SerialTool_CSharp { public class Program { SerialPort serialPort; public static void Main() { serialPort = new SerialPort("COM3", 115200); serialPort.Open(); serialPort.WriteLine($"From {serialPort.PortName}, Hello"); serialPort.Close(); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } } } ``` ### <span class="SubTitle">Lab1-3 傳送 Byte 陣列</span> ```C#= using System; using System.IO.Ports; namespace SerialTool_CSharp { public class Program { public static void Main() { SerialPort serialPort = new SerialPort("COM3", 115200); serialPort.Open(); Byte[] packet = new Byte[] { 0x30, 0x31, 0x32, 0x33, 0x34 }; serialPort.Write(packet, 0, packet.Length); serialPort.Close(); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } } } ``` ### <span class="SubTitle">Lab1-4 每 500ms 傳送 Byte 陣列</span> ```C#= using System; using System.IO.Ports; namespace SerialTool_CSharp { public class Program { public static void Main() { SerialPort serialPort = new SerialPort("COM3", 115200); serialPort.Open(); Byte[] packet = new Byte[] { 0x30, 0x31, 0x32, 0x33, 0x34 }; DateTime dt1 = new DateTime(); while (true) { if (new TimeSpan(DateTime.Now.Ticks - dt1.Ticks).TotalMilliseconds > 500) { dt1 = DateTime.Now; serialPort.Write(packet, 0, packet.Length); } } serialPort.Close(); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } } } ``` ## <span class="Title">主題2. 使用 Thread </span> ### <span class="SubTitle">Lab2-1 導入 Thread(),可以在傳送的時候,輸入 ENTER 來結束程序</span> ```C#= using System; using System.IO.Ports; using System.Threading; namespace SerialTool_CSharp { public class Program { public static void transmitMsg() { SerialPort serialPort = new SerialPort("COM3", 115200); serialPort.Open(); Byte[] packet = new Byte[] { 0x30, 0x31, 0x32, 0x33, 0x34 }; DateTime dt1 = new DateTime(); Console.Write("Transmitting"); while (true) { if (new TimeSpan(DateTime.Now.Ticks - dt1.Ticks).TotalMilliseconds > 500) { dt1 = DateTime.Now; serialPort.Write(packet, 0, packet.Length); Console.Write("."); } } } public static void Main() { var t = new Thread(transmitMsg); t.Start(); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); t.Abort(); } } } ``` ### <span class="SubTitle">Lab2-2 Thread 開始前,可以指定 packet 內容進行傳送</span> ```C#= using System; using System.IO.Ports; using System.Threading; namespace SerialTool_CSharp { public class Program { public static void transmitMsg() { SerialPort serialPort = new SerialPort("COM3", 115200); serialPort.Open(); Byte[] packet = new Byte[] { 0x30, 0x31, 0x32, 0x33, 0x34 }; DateTime dt1 = new DateTime(); Console.Write("Transmitting"); while (true) { if (new TimeSpan(DateTime.Now.Ticks - dt1.Ticks).TotalMilliseconds > 500) { dt1 = DateTime.Now; serialPort.Write(packet, 0, packet.Length); Console.Write("."); } } } public static void transmitWithMsg(Object msg) { SerialPort serialPort = new SerialPort("COM3", 115200); serialPort.Open(); Byte[] packet = (Byte[])msg; DateTime dt1 = new DateTime(); Console.Write("Transmitting"); while (true) { if (new TimeSpan(DateTime.Now.Ticks - dt1.Ticks).TotalMilliseconds > 500) { dt1 = DateTime.Now; serialPort.Write(packet, 0, packet.Length); Console.Write("."); } } } public static void Main() { var t = new Thread(transmitWithMsg); Byte[] packet = new Byte[] { 0x65, 0x66, 0x67, 0x68, 0x69 }; t.Start(packet); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); t.Abort(); } } } ``` ## <span class="Title">主題3. 讀取 </span> ### <span class="SubTitle">Lab3-1 讀取字串 </span> ```C#= using System; using System.IO.Ports; namespace SerialTool_CSharp { public class Program { public static void Main() { SerialPort serialPort = new SerialPort("COM3", 115200); serialPort.Open(); string str = serialPort.ReadLine(); serialPort.Close(); Console.WriteLine($"從 {serialPort.PortName} 收到 {str}"); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } } } ``` ### <span class="SubTitle">Lab3-2 讀取 Byte 陣列 </span> ```C#= using System; using System.IO.Ports; namespace SerialTool_CSharp { public class Program { public static void Main() { SerialPort serialPort = new SerialPort("COM3", 115200); serialPort.Open(); Byte[] packet = new Byte[10]; int readBytes = serialPort.Read(packet, 0, packet.Length); serialPort.Close(); Console.WriteLine($"從 {serialPort.PortName} 收到"); for (int i = 0; i < readBytes; i++) { Console.Write(String.Format("0x{0:X} ,", packet[i])); } Console.WriteLine(); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); } } } ``` ### <span class="SubTitle">Lab3-3 使用 DataReceived <font color =#ff0>event</font> 讀取 Byte 陣列 </span> <font color = "Red">以下程式是無法編譯</font> ```C#= using System; using System.IO.Ports; namespace SerialTool_CSharp { public class Program { private static void DataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e) { SerialPort serialPort = (SerialPort)sender; Byte[] packet = new Byte[serialPort.BytesToRead]; int readBytes = serialPort.Read(packet, 0, packet.Length); Console.WriteLine($"從 {serialPort.PortName} 收到"); for (int i = 0; i < readBytes; i++) { Console.Write(String.Format("0x{0:X} ,", packet[i])); } Console.WriteLine(); } public static void Main() { SerialPort serialPort = new SerialPort("COM3", 115200); serialPort.DataReceived += DataReceivedEventHandler; serialPort.Open(); Console.WriteLine("Press ENTER to exit."); Console.ReadLine(); serialPort.Close(); } } } ``` :::spoiler 補充說明 註冊事件 ![](https://i.imgur.com/BbmYdWl.png) <span class="Figure">(Fig.3-1)</span> SerialPort 的 DataReceived 是一個 **SerialDataReceivedEventHandler** 型別的事件 ![](https://i.imgur.com/O36y7gp.png) <span class="Figure">(Fig.3-2)</span> **SerialDataReceivedEventHandler** 是一種 <font color =#ff0>delegate</font> 型別 ![](https://i.imgur.com/EwR1ylb.png) <span class="Figure">(Fig. 3-3)</span> :::