using SerialPortUtility; using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; public class SerialPortExample : MonoBehaviour { public int baudrate = 115200; public SerialPortUtilityPro serialPortUtility; public SerialPortUtilityPro.OpenSystem openMode = SerialPortUtilityPro.OpenSystem.PCI; private static int baseAddress; private static int offsetAddress; private Queue tempDataQueue; public string PortName = ""; private int coinsAmount = 0; private const int SlotCount = 1; bool urlBack = false; byte dataIndex = 1; private void Awake() { DontDestroyOnLoad(gameObject); } private void Start() { serialPortUtility = gameObject.GetComponent(); serialPortUtility.OpenMethod = openMode; serialPortUtility.DeviceName = PortName; serialPortUtility.StopBit = SerialPortUtilityPro.StopBitEnum.OneBit; serialPortUtility.DataBit = SerialPortUtilityPro.DataBitEnum.EightBit; serialPortUtility.Open(); //serialPortUtility.ReadCompleteEventObject.AddListener(ReadStreamingBinary); //byte[] datas = new byte[8] { 0xAA, 0x08, 0x04, 0x01, 0x00, 0x00, 0x3C, 0xBB }; //serialPortUtility.Write(datas); if (PortName.Contains("/dev/ttyS0")) RequestUrl(dataIndex); } void Update() { #region 测试代码 #if UNITY_EDITOR if (Input.GetMouseButtonDown(0)) { //TestPayQR(); } #endif #endregion //if (serialPortUtility != null && serialPortUtility.IsOpened()) // { // Debug.Log(serialPortUtility.GetSerialDebugString); // Debug.Log("串口接收到数据"); // } } void TestPay() { if (!PortName.Contains("/dev/ttyS0")) return; Debug.LogError("TestPay"); List data = new List(); data.Add(0XAA); data.Add(0X55);//帧头 data.Add(0x04);//帧长度 data.Add(0x01);//数据编号 data.Add(0XA6);//指令 data.Add(0X01);//数据 data.Add(0X00);//校验位 PrintFrame(data.ToArray()); } void TestPayQR() { if (!PortName.Contains("/dev/ttyS0")) return; List data = new List(); data.Add(0XAA); data.Add(0X55);//帧头 data.Add(0x05);//帧长度 data.Add(0xDA);//数据编号 data.Add(0XA1);//指令 data.Add(0X02);//数据 data.Add(0X64);//数据 byte temp = 0; for (int i = 2; i < data.Count; i++) { temp ^= data[i]; } data.Add(temp);//校验位 Debug.LogError($"TestPayQR temp={temp}"); PrintFrame(data.ToArray()); } void OnUrlPayResponse(byte[] bytes) { if (!PortName.Contains("/dev/ttyS0")) return; //计算校验值 byte tempResponseCheck = 0; for (int i = 2; i < bytes.Length - 1; i++) { tempResponseCheck ^= bytes[i]; } byte responseCheck = bytes[bytes.Length - 1]; //回复云上分 List response = new List(); response.Add(0XAA); response.Add(0X55);//帧头 response.Add(0X04);//帧长 var dataIndex = bytes[3]; response.Add(dataIndex);//数据编号 response.Add(0XA1);//数据编号 var data = responseCheck == tempResponseCheck ? 0X01 : 0x00; response.Add((byte)data);//数据 var endIdx = bytes[3]; byte temp = 0; for (int i = 2; i < response.Count; i++) { temp ^= response[i]; } response.Add(temp);//校验位 Debug.LogError($"responseCheck={responseCheck} tempResponseCheck={tempResponseCheck} data ={data} dataIndex={dataIndex} temp={temp}"); serialPortUtility.Write(response.ToArray()); if (data == 0X01) StandaloneAPI.InsertCoint(bytes[6]); } /// /// 串口读取二进制流数据 /// /// public void ReadStreamingBinary(object data) { var bin = data as byte[]; PrintFrame(bin); } void PrintFrame(byte[] bytes) { if (bytes[0] == 0xAA) { if (bytes[1] == 0x55)//旧 { if (bytes[4] == 0xA6)//投币 { Debug.Log("旧版投币数量:" + bytes[4]); StandaloneAPI.InsertCoint(bytes[5]); } else if (bytes[4] == 0xAA) //支付盒子链接请求返回 OnUrlResponse(bytes); else if (bytes[4] == 0xA1) //支付盒子支付返回(云上分) OnUrlPayResponse(bytes); } else { //Debug.Log("bytes[1]命令:" + bytes[1] + "bytes[2]命令:" + bytes[2]); Debug.Log("接收到的串口命令:" + bytes[0] + bytes[1] + bytes[2] + bytes[3] + bytes[4] + bytes[5]); //0x04:为按键是否按下的命令 if (bytes[1] == 0x04)//退出 { Debug.Log("确认按键退出游戏命令"); if (bytes[3] == 0x01) { Debug.Log("确认按下按键"); AimHandler.ins.ExitIntoEvent(); SendMessage(bytes, 3); return; } else if(bytes[3] == 0x00) { Debug.Log("松开按键"); SendMessage(bytes, 3); return; } } else if (bytes[1] == 01)//投币 { Debug.Log("确认投币命令"); StandaloneAPI.InsertCoint(bytes[3]); SendMessage(bytes, 3); } } } } /// /// 请求二维码链接 /// /// 数据编号 从1开始 private void RequestUrl(byte dataIndex) { byte[] datas = new byte[7] { 0xAA, 0x55, 0x04, dataIndex, 0xAA, 0x01, 0xAE }; datas[6] = GetXor(datas); serialPortUtility.Write(datas); Invoke("CheckURLBack", 5f); #if UNITY_EDITOR TestBackUrl(); #endif } private void CheckURLBack() { if (!urlBack && dataIndex <= 3) { Debug.LogWarning("没有拉取到支付url"); RequestUrl(++dataIndex); } } /// /// 测试URL回包 /// private void TestBackUrl() { var url = $"http://pay.sy1999.com:8901?productNumber=SY4G4365"; var urlData = System.Text.UTF8Encoding.Default.GetBytes(url); List data = new List(); data.Add(0XAA); data.Add(0X55);//帧头 data.Add((byte)(urlData.Length + 3));//帧长度(数据编号到校验位的所有数据长度) data.Add(0X01);//数据编号 data.Add(0XAA);//指令 data.AddRange(urlData);//数据 data.Add(0X00);//校验位 Debug.Log($"Test: url={url} length={urlData.Length}"); PrintFrame(data.ToArray()); } /// /// URL请求返回 /// /// void OnUrlResponse(byte[] bytes) { urlBack = true; Debug.Log("开始解析二维码数组"); int frameLength = bytes[2]; Debug.Log("帧长度" + frameLength); frameLength = frameLength - 3; Debug.Log("解析后的数据长度:" + frameLength); List datas = new List(); var startPos = 5; for (int i = startPos; i < frameLength + startPos; i++) { datas.Add(bytes[i]); } byte[] bs = datas.ToArray(); var url = System.Text.Encoding.Default.GetString(bs); StandaloneAPI.url = url; var homeView = FindObjectOfType(); if (homeView != null) homeView.FlushUrlQR(); } void SendMessage(byte[] bytes,int index) { List s = new List(bytes); s.RemoveAt(index); bytes = s.ToArray(); serialPortUtility.Write(bytes); } byte GetXor(byte[] btyes) { byte temp = 0; for (int i = 2; i < btyes.Length; i++) { temp ^= btyes[i]; } return temp; } private void OnDestroy() { Debug.Log("串口程序被销毁"); serialPortUtility.Close(); } }