1
0
mirror of synced 2024-12-20 02:05:54 +01:00
WACVR/Assets/Script/Serial.cs

316 lines
10 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.IO.Ports;
using System.Linq;
using UnityEngine;
public class Serial : MonoBehaviour
{
const byte CMD_GET_SYNC_BOARD_VER = 0xa0;
const byte CMD_NEXT_READ = 0x72;
const byte CMD_GET_UNIT_BOARD_VER = 0xa8;
const byte CMD_MYSTERY1 = 0xa2;
const byte CMD_MYSTERY2 = 0x94;
const byte CMD_START_AUTO_SCAN = 0xc9;
const byte CMD_BEGIN_WRITE = 0x77;
const byte CMD_NEXT_WRITE = 0x20;
private Thread _touchThread;
private Queue _touchQueue;
static SerialPort ComL = new SerialPort ("COM5", 115200);
static SerialPort ComR = new SerialPort ("COM6", 115200);
byte inByte;
string SYNC_BOARD_VER = "190523";
string UNIT_BOARD_VER = "190514";
string read1 = " 0 0 1 2 3 4 5 15 15 15 15 15 15 11 11 11";
string read2 = " 11 11 11 128 103 103 115 138 127 103 105 111 126 113 95 100";
string read3 = " 101 115 98 86 76 67 68 48 117 0 82 154 0 6 35 4";
byte[] SettingData_160 = new byte[8];
byte[] SettingData_162 = new byte[7];
byte[] SettingData_148 = new byte[7];
byte[] SettingData_201 = new byte[7];
static byte[] TouchPackL = new byte[36];
static byte[] TouchPackR = new byte[36];
public static bool[] TouchPackAll = new bool[240];
bool StartUp = false;
void Start()
{
try
{
ComL.Open();
ComR.Open();
}
catch (Exception ex)
{
Console.WriteLine($"Failed to Open Serial Ports: {ex}");
}
//Debug.Log("Touch Serial Initializing..");
SetSettingData_160();
SetSettingData_201();
SetSettingData_162();
SetSettingData_148();
//Send touch update periodically to keep "read" alive
_touchQueue = Queue.Synchronized(new Queue());
_touchThread = new Thread(TouchThreadLoop);
InvokeRepeating("PingTouchThread", 0, 1);
//Send touch updates whenever actual state changes to achieve desired update frequency without overloading
ColliderToSerial.touchDidChange += PingTouchThread;
}
private void PingTouchThread()
{
_touchQueue.Enqueue(1);
}
private void TouchThreadLoop()
{
while(true)
{
if(_touchQueue.Count > 0)
{
_touchQueue.Dequeue();
SendTouchState();
}
}
}
private void OnDestroy()
{
ComL.Close();
ComR.Close();
}
void Update()
{
if(ComL.IsOpen)
ReadHead(ComL, 0);
if (ComR.IsOpen)
ReadHead(ComR, 1);
// if (Input.GetKeyDown(KeyCode.M)) //this is a touch test code
// StartCoroutine(TouchTest(true));
if (Input.GetKeyDown(KeyCode.M) && StartUp)
SendTouchState();
}
private void SendTouchState()
{
if(StartUp)
{
//Debug.Log("Sending Touch State");
// Debug.Log("Sending Left");
SendTouch(ComL, TouchPackL);
// Debug.Log("Sending Right");
SendTouch(ComR, TouchPackR);
}
}
private void FixedUpdate() {
//SendTouchState();
}
IEnumerator TouchTest(bool State) //this is a touch test code
{
for (int i = 0; i < 240; i++)
{
SetTouch(i, true);
Debug.Log(i);
yield return new WaitForSeconds(0.05f);
SetTouch(i, false);
yield return new WaitForSeconds(0.05f);
}
}
void ReadHead(SerialPort Serial, int side) //Read head byte
{
if(Serial.BytesToRead > 0)
{
inByte = Convert.ToByte(Serial.ReadByte());
var data = Serial.ReadExisting();
SendResp(Serial, side, data);
}
}
void SendResp(SerialPort Serial, int side, string data)
{
switch(inByte)
{
case CMD_GET_SYNC_BOARD_VER:
//Response: cmd byte + sync board ver + checksum
StartUp = false;
List<byte> syncbytes = new List<byte>();
syncbytes.Add(inByte);
syncbytes.AddRange(ByteHelper.ConvertStringToByteArray(SYNC_BOARD_VER));
byte syncCheckSum = (byte)44;
syncbytes.Add(syncCheckSum);
Serial.Write(syncbytes.ToArray(), 0, syncbytes.Count);
//Debug.Log($"GET SYNC BOARD VER {side}");
break;
case CMD_NEXT_READ:
//Response: corresponding read bytes + checksum
StartUp = false;
//Debug.Log($"Side {side} NEXT READ {Convert.ToByte(data[2])}");
switch (Convert.ToByte(data[2]))
{
case 0x30:
var bytes = ByteHelper.ConvertStringToByteArray(read1);
bytes.Add(ByteHelper.CalCheckSum(bytes.ToArray(), bytes.Count));
//Debug.Log("Read 1");
Serial.Write(bytes.ToArray(), 0, bytes.Count);
break;
case 0x31:
var bytes2 = ByteHelper.ConvertStringToByteArray(read2);
bytes2.Add(ByteHelper.CalCheckSum(bytes2.ToArray(), bytes2.Count));
//Debug.Log("Read 2");
Serial.Write(bytes2.ToArray(), 0, bytes2.Count);
break;
case 0x33:
var bytes3 = ByteHelper.ConvertStringToByteArray(read3);
bytes3.Add(ByteHelper.CalCheckSum(bytes3.ToArray(), bytes3.Count));
//Debug.Log("Read 3");
Serial.Write(bytes3.ToArray(), 0, bytes3.Count);
break;
default:
//Debug.Log("Extra Read");
break;
}
break;
case CMD_GET_UNIT_BOARD_VER:
//Response: cmd byte + sync board ver bytes + 'L'/'R' based on side + unit board ver bytes x6 + checksum
StartUp = false;
List<byte> unitBytes = new List<byte>();
byte sideByte = (side == 0 ? Convert.ToByte('R') : Convert.ToByte('L'));
byte unitCheckSum = (side == 0 ? (byte)118 : (byte)104);
unitBytes.Add(inByte);
unitBytes.AddRange(ByteHelper.ConvertStringToByteArray(SYNC_BOARD_VER));
unitBytes.Add(sideByte);
for (int i = 0; i < 6; i++)
unitBytes.AddRange(ByteHelper.ConvertStringToByteArray(UNIT_BOARD_VER));
unitBytes.Add(unitCheckSum);
Serial.Write(unitBytes.ToArray(), 0, unitBytes.Count);
//Debug.Log($"GET UNIT BOARD VER {side}");
break;
case CMD_MYSTERY1:
StartUp = false;
Serial.Write(SettingData_162, 0, 3);
//Debug.Log($"MYSTERY 1 SIDE {side}");
break;
case CMD_MYSTERY2:
StartUp = false;
Serial.Write(SettingData_148, 0, 3);
//Debug.Log($"MYSTERY 2 SIDE {side}");
break;
case CMD_START_AUTO_SCAN:
Serial.Write(SettingData_201.ToArray(), 0, 3);
//Debug.Log($"START AUTO SCAN SIDE {side}");
StartUp = true;
if (!_touchThread.IsAlive)
_touchThread.Start();
break;
case CMD_BEGIN_WRITE:
// Debug.Log($"Begin Write For Side {side}");
break;
case CMD_NEXT_WRITE:
// Debug.Log($"Continue Write For Side {side}");
break;
case 154:
StartUp = false;
//Debug.Log("BAD");
break;
}
}
byte[] GetTouchPack(byte[] Pack) //convert touch to right format for game
{
Pack[0] = 129;
Pack[34] = Pack[34]++;
Pack[35] = 128;
Pack[35] = ByteHelper.CalCheckSum(Pack, 36);
if (Pack[34] > 127)
Pack[34] = 0;
return Pack;
}
void SendTouch(SerialPort Serial, byte[] Pack) //Send touch data
{
if (StartUp)
{
// Debug.Log($"Pack {string.Join(" ", Pack)}");
var output = GetTouchPack(Pack);
// Debug.Log($"Output {string.Join(" ", output)}");
Serial.Write(output, 0, 36);
}
}
public static void SetTouch(int Area, bool State) //set touch data 0-239
{
//Area +=1;
if (Area < 121)
{
Area += (Area-1) / 5 * 3 + 7;
ByteHelper.SetBit(TouchPackR, Area, State);
}
else if (Area >= 120)
{
Area -= 120;
Area += (Area-1) / 5 * 3 + 7;
ByteHelper.SetBit(TouchPackL, Area, State);
}
TouchPackAll[Area] = State;
}
void SetSettingData_160()
{
SettingData_160[0]=160;
SettingData_160[1]=49;
SettingData_160[2]=57;
SettingData_160[3]=48;
SettingData_160[4]=53;
SettingData_160[5]=50;
SettingData_160[6]=51;
SettingData_160[7]=44;
}
void SetSettingData_201()
{
SettingData_201[0]=201;
SettingData_201[1]=0;
SettingData_201[2]=73;
}
void SetSettingData_162()
{
SettingData_162[0]=162;
SettingData_162[1]=63;
SettingData_162[2]=29;
}
void SetSettingData_148()
{
SettingData_148[0]=148;
SettingData_148[1]=0;
SettingData_148[2]=20;
}
}
public static class ByteHelper
{
public static byte[] SetBit(this byte[] self, int index, bool value)
{
var bitArray = new BitArray(self);
bitArray.Set(index, value);
bitArray.CopyTo(self, 0);
return self;
}
public static byte CalCheckSum(byte[] _PacketData,int PacketLength)
{
Byte _CheckSumByte = 0x00;
for (int i = 0; i < PacketLength; i++)
_CheckSumByte ^= _PacketData[i];
return _CheckSumByte;
}
public static List<byte> ConvertStringToByteArray(string data)
{
List<byte> tempList = new List<byte>(100);
for(int i = 0; i < data.Length; i++)
tempList.Add(Convert.ToByte(data[i]));
return tempList;
}
}