项目上有需求要控制投影机一键开和关,在主控主机上写一个中控软件控制,在网上查了一些资料,投影机都可通过串口线来控制(部分可以用网口控制),这里我用的是串口控制,首先要拿到投影机的中控代码,直接找厂商要,公司用的是松下的PT-X3270,下面是中控代码。
串口9针头 3是接收,2是发送,5是接地 波 特 率:19200bps 数 据 位:8位 停 止 位:1位 奇偶校验:无 同步方式:不同步 X参数:无 S参数:无 投影机开:02504F4E03 投影机关:02504F4603 电 脑1:024949533A52473103 电 脑2:024949533A52473203 视 频:024949533A56494403 H D M I:024949533A48443103有了中控代码就很简单了,剩下的就是利用串口发数据了,关于串口就不多说了,网上很多。考虑到可能会控制不同型号的投影机,决定用XML来配置一些参数,要用到的重要参数也就3个,一个是波特率,不同型号的波特率可能会不一样,然后就是投影开关的串口数据了,这次用到两种型号的投影。
写一个存投影机数据的类
废话不多说了,下面就是xml的读取,和串口发送数据了,直接上代码。
public class PortCtrl_2 : MonoBehiour { private string portName = "COM14"; private int baudRate = 9600;//波特率 private Parity parity = Parity.None;//奇偶校验 private int dataBits = 8;//数据位 private StopBits stopBits = StopBits.One;//停止位 private string openStr = "02504F4E03"; private string closeStr = "02504F4603"; private Button btn_1_open; private Button btn_1_close; private Button btn_2_open; private Button btn_2_close; private DataConfig[] datas = new DataConfig[2]; private SerialPort[] ports = new SerialPort[2]; private string xmlPath; private void Start() { xmlPath = Application.streamingAssetsPath + "/ctrl2.xml"; LoadXml(xmlPath); OpenPort(); //投影1--18 btn_1_open = GameObject.Find("Canvas/BG/View1/Open").GetComponent(); btn_1_open.onClick.AddListener(() => WriteData(ports[0], datas[0].openStr)); btn_1_close = GameObject.Find("Canvas/BG/View1/Close").GetComponent(); btn_1_close.onClick.AddListener(() => WriteData(ports[0], datas[0].closeStr)); //投影4-1--4-4 btn_2_open = GameObject.Find("Canvas/BG/View2/Open").GetComponent(); btn_2_open.onClick.AddListener(() => WriteData(ports[1], datas[1].openStr)); btn_2_close = GameObject.Find("Canvas/BG/View2/Close").GetComponent(); btn_2_close.onClick.AddListener(() => WriteData(ports[1], datas[1].closeStr)); } private void OpenPort() { for (int i = 0; i < datas.Length; i++) { SerialPort port = ports[i]; ports[i] = new SerialPort("\\\\.\\" + datas[i].portName, datas[i].baudRate, parity, dataBits, stopBits); ports[i].ReadTimeout = 400; ports[i].WriteTimeout = 400; try { ports[i].Open(); Debug.Log("打开串口......"); } catch (Exception ex) { Debug.Log(ex.Message); } } } private void ClosePort() { try { //关闭串口和接收线程 for (int i = 0; i < ports.Length; i++) { if (ports[i].IsOpen) { ports[i].Close(); } } } catch (Exception ex) { Debug.Log(ex.Message); } } private void WriteData(SerialPort port, string str) { if (port.IsOpen) { byte[] array = strToHexByte(str); port.Write(array, 0, array.Length); } } private void OnApplicationQuit() { ClosePort(); } private void Open(SerialPort port) { WriteData(port, openStr); } private void Close(SerialPort port) { WriteData(port, closeStr); } private void LoadXml(string path) { if (File.Exists(xmlPath)) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(path); XmlNodeList list = xmlDoc.SelectSingleNode("dataConfig").ChildNodes; XmlElement element1 = list[0] as XmlElement; portName = element1.GetAttribute("portName"); for (int i = 0; i < datas.Length; i++) { XmlElement element = list[i] as XmlElement; datas[i] = new DataConfig(element); } } } //16进制字符串转字节数组 private byte[] strToHexByte(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; } //字节数组转16进制字符串 public static string byteToHexStr(byte[] bytes) { string returnStr = ""; if (bytes != null) { for (int i = 0; i < bytes.Length; i++) { returnStr += bytes[i].ToString("X2"); } } return returnStr; } }