项目上有需求要控制投影机一键开和关,在主控主机上写一个中控软件控制,在网上查了一些资料,投影机都可通过串口线来控制(部分可以用网口控制),这里我用的是串口控制,首先要拿到投影机的中控代码,直接找厂商要,公司用的是松下的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个,一个是波特率,不同型号的波特率可能会不一样,然后就是投影开关的串口数据了,这次用到两种型号的投影。
写一个存投影机数据的类
public class DataConfig
{
public int id;
public string portName;
public int baudRate;
public string openStr;
public string closeStr;
public DataConfig(XmlElement element)
{
id = int.Parse(element.GetAttribute("id"));
portName = element.GetAttribute("portName");
baudRate = int.Parse(element.GetAttribute("baudRate"));
openStr = element.GetAttribute("openStr");
closeStr = element.GetAttribute("closeStr");
}
}
废话不多说了,下面就是xml的读取,和串口发送数据了,直接上代码。
public class PortCtrl_2 : MonoBehaviour
{
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<Button>();
btn_1_open.onClick.AddListener(() => WriteData(ports[0], datas[0].openStr));
btn_1_close = GameObject.Find("Canvas/BG/View1/Close").GetComponent<Button>();
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<Button>();
btn_2_open.onClick.AddListener(() => WriteData(ports[1], datas[1].openStr));
btn_2_close = GameObject.Find("Canvas/BG/View2/Close").GetComponent<Button>();
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;
}
}