SerialPortExample.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. using SerialPortUtility;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using UnityEngine;
  7. public class SerialPortExample : MonoBehaviour
  8. {
  9. public int baudrate = 115200;
  10. public SerialPortUtilityPro serialPortUtility;
  11. public SerialPortUtilityPro.OpenSystem openMode = SerialPortUtilityPro.OpenSystem.PCI;
  12. private static int baseAddress;
  13. private static int offsetAddress;
  14. private Queue<byte> tempDataQueue;
  15. public string PortName = "";
  16. private int coinsAmount = 0;
  17. private const int SlotCount = 1;
  18. bool urlBack = false;
  19. byte dataIndex = 1;
  20. private void Awake()
  21. {
  22. DontDestroyOnLoad(gameObject);
  23. }
  24. private void Start()
  25. {
  26. serialPortUtility = gameObject.GetComponent<SerialPortUtilityPro>();
  27. serialPortUtility.OpenMethod = openMode;
  28. serialPortUtility.DeviceName = PortName;
  29. serialPortUtility.StopBit = SerialPortUtilityPro.StopBitEnum.OneBit;
  30. serialPortUtility.DataBit = SerialPortUtilityPro.DataBitEnum.EightBit;
  31. serialPortUtility.Open();
  32. //serialPortUtility.ReadCompleteEventObject.AddListener(ReadStreamingBinary);
  33. //byte[] datas = new byte[8] { 0xAA, 0x08, 0x04, 0x01, 0x00, 0x00, 0x3C, 0xBB };
  34. //serialPortUtility.Write(datas);
  35. if (PortName.Contains("/dev/ttyS0"))
  36. RequestUrl(dataIndex);
  37. }
  38. void Update()
  39. {
  40. #region 测试代码
  41. #if UNITY_EDITOR
  42. if (Input.GetMouseButtonDown(0))
  43. {
  44. //TestPayQR();
  45. }
  46. #endif
  47. #endregion
  48. //if (serialPortUtility != null && serialPortUtility.IsOpened())
  49. // {
  50. // Debug.Log(serialPortUtility.GetSerialDebugString);
  51. // Debug.Log("串口接收到数据");
  52. // }
  53. }
  54. void TestPay()
  55. {
  56. if (!PortName.Contains("/dev/ttyS0"))
  57. return;
  58. Debug.LogError("TestPay");
  59. List<byte> data = new List<byte>();
  60. data.Add(0XAA);
  61. data.Add(0X55);//帧头
  62. data.Add(0x04);//帧长度
  63. data.Add(0x01);//数据编号
  64. data.Add(0XA6);//指令
  65. data.Add(0X01);//数据
  66. data.Add(0X00);//校验位
  67. PrintFrame(data.ToArray());
  68. }
  69. void TestPayQR()
  70. {
  71. if (!PortName.Contains("/dev/ttyS0"))
  72. return;
  73. List<byte> data = new List<byte>();
  74. data.Add(0XAA);
  75. data.Add(0X55);//帧头
  76. data.Add(0x05);//帧长度
  77. data.Add(0xDA);//数据编号
  78. data.Add(0XA1);//指令
  79. data.Add(0X02);//数据
  80. data.Add(0X64);//数据
  81. byte temp = 0;
  82. for (int i = 2; i < data.Count; i++)
  83. {
  84. temp ^= data[i];
  85. }
  86. data.Add(temp);//校验位
  87. Debug.LogError($"TestPayQR temp={temp}");
  88. PrintFrame(data.ToArray());
  89. }
  90. void OnUrlPayResponse(byte[] bytes)
  91. {
  92. if (!PortName.Contains("/dev/ttyS0"))
  93. return;
  94. //计算校验值
  95. byte tempResponseCheck = 0;
  96. for (int i = 2; i < bytes.Length - 1; i++)
  97. {
  98. tempResponseCheck ^= bytes[i];
  99. }
  100. byte responseCheck = bytes[bytes.Length - 1];
  101. //回复云上分
  102. List<byte> response = new List<byte>();
  103. response.Add(0XAA);
  104. response.Add(0X55);//帧头
  105. response.Add(0X04);//帧长
  106. var dataIndex = bytes[3];
  107. response.Add(dataIndex);//数据编号
  108. response.Add(0XA1);//数据编号
  109. var data = responseCheck == tempResponseCheck ? 0X01 : 0x00;
  110. response.Add((byte)data);//数据
  111. var endIdx = bytes[3];
  112. byte temp = 0;
  113. for (int i = 2; i < response.Count; i++)
  114. {
  115. temp ^= response[i];
  116. }
  117. response.Add(temp);//校验位
  118. Debug.LogError($"responseCheck={responseCheck} tempResponseCheck={tempResponseCheck} data ={data} dataIndex={dataIndex} temp={temp}");
  119. serialPortUtility.Write(response.ToArray());
  120. if (data == 0X01)
  121. StandaloneAPI.InsertCoint(bytes[6]);
  122. }
  123. /// <summary>
  124. /// 串口读取二进制流数据
  125. /// </summary>
  126. /// <param name="data"></param>
  127. public void ReadStreamingBinary(object data)
  128. {
  129. var bin = data as byte[];
  130. PrintFrame(bin);
  131. }
  132. void PrintFrame(byte[] bytes)
  133. {
  134. if (bytes[0] == 0xAA)
  135. {
  136. if (bytes[1] == 0x55)//旧
  137. {
  138. if (bytes[4] == 0xA6)//投币
  139. {
  140. Debug.Log("旧版投币数量:" + bytes[4]);
  141. StandaloneAPI.InsertCoint(bytes[5]);
  142. }
  143. else if (bytes[4] == 0xAA) //支付盒子链接请求返回
  144. OnUrlResponse(bytes);
  145. else if (bytes[4] == 0xA1) //支付盒子支付返回(云上分)
  146. OnUrlPayResponse(bytes);
  147. }
  148. else
  149. {
  150. //Debug.Log("bytes[1]命令:" + bytes[1] + "bytes[2]命令:" + bytes[2]);
  151. Debug.Log("接收到的串口命令:" + bytes[0] + bytes[1] + bytes[2] + bytes[3] + bytes[4] + bytes[5]);
  152. //0x04:为按键是否按下的命令
  153. if (bytes[1] == 0x04)//退出
  154. {
  155. Debug.Log("确认按键退出游戏命令");
  156. if (bytes[3] == 0x01)
  157. {
  158. Debug.Log("确认按下按键");
  159. AimHandler.ins.ExitIntoEvent();
  160. SendMessage(bytes, 3);
  161. return;
  162. }
  163. else if(bytes[3] == 0x00)
  164. {
  165. Debug.Log("松开按键");
  166. SendMessage(bytes, 3);
  167. return;
  168. }
  169. }
  170. else if (bytes[1] == 01)//投币
  171. {
  172. Debug.Log("确认投币命令");
  173. StandaloneAPI.InsertCoint(bytes[3]);
  174. SendMessage(bytes, 3);
  175. }
  176. }
  177. }
  178. }
  179. /// <summary>
  180. /// 请求二维码链接
  181. /// </summary>
  182. /// <param name="dataIndex">数据编号 从1开始</param>
  183. private void RequestUrl(byte dataIndex)
  184. {
  185. byte[] datas = new byte[7] { 0xAA, 0x55, 0x04, dataIndex, 0xAA, 0x01, 0xAE };
  186. datas[6] = GetXor(datas);
  187. serialPortUtility.Write(datas);
  188. Invoke("CheckURLBack", 5f);
  189. #if UNITY_EDITOR
  190. TestBackUrl();
  191. #endif
  192. }
  193. private void CheckURLBack()
  194. {
  195. if (!urlBack && dataIndex <= 3)
  196. {
  197. Debug.LogWarning("没有拉取到支付url");
  198. RequestUrl(++dataIndex);
  199. }
  200. }
  201. /// <summary>
  202. /// 测试URL回包
  203. /// </summary>
  204. private void TestBackUrl()
  205. {
  206. var url = $"http://pay.sy1999.com:8901?productNumber=SY4G4365";
  207. var urlData = System.Text.UTF8Encoding.Default.GetBytes(url);
  208. List<byte> data = new List<byte>();
  209. data.Add(0XAA); data.Add(0X55);//帧头
  210. data.Add((byte)(urlData.Length + 3));//帧长度(数据编号到校验位的所有数据长度)
  211. data.Add(0X01);//数据编号
  212. data.Add(0XAA);//指令
  213. data.AddRange(urlData);//数据
  214. data.Add(0X00);//校验位
  215. Debug.Log($"Test: url={url} length={urlData.Length}");
  216. PrintFrame(data.ToArray());
  217. }
  218. /// <summary>
  219. /// URL请求返回
  220. /// </summary>
  221. /// <param name="data"></param>
  222. void OnUrlResponse(byte[] bytes)
  223. {
  224. urlBack = true;
  225. Debug.Log("开始解析二维码数组");
  226. int frameLength = bytes[2];
  227. Debug.Log("帧长度" + frameLength);
  228. frameLength = frameLength - 3;
  229. Debug.Log("解析后的数据长度:" + frameLength);
  230. List<byte> datas = new List<byte>();
  231. var startPos = 5;
  232. for (int i = startPos; i < frameLength + startPos; i++)
  233. {
  234. datas.Add(bytes[i]);
  235. }
  236. byte[] bs = datas.ToArray();
  237. var url = System.Text.Encoding.Default.GetString(bs);
  238. StandaloneAPI.url = url;
  239. var homeView = FindObjectOfType<HomeView>();
  240. if (homeView != null)
  241. homeView.FlushUrlQR();
  242. }
  243. void SendMessage(byte[] bytes,int index)
  244. {
  245. List<byte> s = new List<byte>(bytes);
  246. s.RemoveAt(index);
  247. bytes = s.ToArray();
  248. serialPortUtility.Write(bytes);
  249. }
  250. byte GetXor(byte[] btyes)
  251. {
  252. byte temp = 0;
  253. for (int i = 2; i < btyes.Length; i++)
  254. {
  255. temp ^= btyes[i];
  256. }
  257. return temp;
  258. }
  259. private void OnDestroy()
  260. {
  261. Debug.Log("串口程序被销毁");
  262. serialPortUtility.Close();
  263. }
  264. }