现在需要做一款 人手动转动转盘,软件内部跟着响应对应的事件
选择的方式有两种:
1. 电容器轴承转动,需要中间链接一块带单片程序转换为232或485数据的板子,从板子出来的232或485口插到主机处理接收到的协议数据;(具体的协议得根据板子内部的来对接,不固定)
2. 编码器轴承转动,可以直接接485模块插到电脑上接收数据(市面上数据协议比较统一,有自由协议和RTU协议,买的时候咨询客服看需要哪种方式----怎么接线也可以咨询客服)
下面就是我所用到的485协议的编码器(自由协议)
市面上应该很多都是这个协议,使用uniy读取--------unity如何使用串口等等我就不多说了,百度很多
下面是我如何读取和处理数据的,每个人需求不一样处理的也就不一样
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
using System.Threading;
public class SeriaportNet
{
/* 波特率19200 其他默认 自动反馈数据 10ms
一组数据共9位(含0位)
data0 AB ------帧头
data1 CD ------帧头
data2 05 ------字节长度
data3 00 ------角度数据
data4 00 ------角度数据
data5 00 ------角度数据
data6 FF ------角度数据
data7 ** ------校验位
data8 ** ------校验位
data9 3D ------帧尾
角度(单位为度) = ( (data3 * 256 + data4) / 1024 ) * 360
----1024 代表单圈 10bit 分辨率 , 如果是单圈 14bit 则是 16384 分辨率越高数值越精确 */
static SeriaportNet instance;
public static SeriaportNet Instance
{
get
{
if (instance == null)
instance = new SeriaportNet();
return instance;
}
}
SerialPort sp;
Thread thread;
Timer tm;
float com_temp = 0;//编码器算角度的公式
public bool is_diyici = true;
public float jiaodu = 0; // 记录开机第一次的一个角度值
public float m_jiaodu_offset = 0;//之后编码器旋转与上一次的偏移量 来计算图文移动的速度快慢
public bool is_zhengzhuan = true;//判断正转与反转 根据编码器角度数值与上一次比较的增加与减少来判断 在360度到0度这个界限之间采取角度判断(不是很准确旋转太快的话有时候有bug)
public bool is_stop = true;//是否编码器没人转动 处于停止状态
float temp = 0;
public float m_offset = 0;
List<byte> list;
public void Init(string m_com, int com_rate)
{
list = new List<byte>();
com_temp = 360.0f / 1024; //C#除法是按被除数类型的算,如果写成360/1024结果会是0
sp = new SerialPort(m_com, com_rate);
if (sp.IsOpen)
sp.Close();
sp.Open();
thread = new Thread(new ThreadStart(DataReceive));
thread.IsBackground = true;
thread.Start();
Handle_Data();
}
/// <summary>
/// 处理接收到的数据
/// </summary>
void Handle_Data()
{
tm = new Timer(0.02f);
tm.Start();
tm.OnEnd += () =>
{
if (list.Count > 20)
{
for (int i = 0; i < list.Count; i++)
{
if (list[i] == 0xAB && list[i + 1] == 0xCD)
{
// Debug.Log(string.Format("{0:X00} {1:X00} {2:X00} {3:X00} {4:X00} {5:X00} {6:X00} {7:X00} {8:X00} {9:X00}", list[i], list[1 + i], list[2 + i], list[3 + i],
// list[4 + i], list[5 + i], list[6 + i], list[7 + i], list[8 + i], list[9 + i]));
float f = (list[3 + i] * 256 + list[4 + i]) * com_temp - m_jiaodu_offset;
// temp = 1 f = 359
if (!is_diyici)
{
if (f > temp)
{
if (f >= 200 && temp > 0 && temp < 100)
{
Debug.Log("反转" + "此刻的角度:" + f.ToString() + "上一个角度:" + temp.ToString());
is_zhengzhuan = false;
m_offset = temp + 360 - f;
}
else
{
Debug.Log("正转" + "此刻的角度:" + f.ToString() + "上一个角度:" + temp.ToString());
is_zhengzhuan = true;
m_offset = f - temp;
}
is_stop = false;
}
else
{
if (f < temp)
{
if (temp >= 200 && f > 0 && f < 100)
{
Debug.Log("正转" + "此刻的角度:" + f.ToString() + "上一个角度:" + temp.ToString());
is_zhengzhuan = true;
m_offset = f + 360 - temp;
}
else
{
Debug.Log("反转" + "此刻的角度:" + f.ToString() + "上一个角度:" + temp.ToString());
is_zhengzhuan = false;
m_offset = temp - f;
}
is_stop = false;
}
else
is_stop = true;
}
}else
{
jiaodu = f; is_diyici = false;
}
temp = f - m_jiaodu_offset;
list.Clear();
}
}
}
Handle_Data();
};
}
/// <summary>
/// 接收串口数据
/// </summary>
void DataReceive()
{
byte[] dataBytes = new byte[255];//存储数据
int bytesToRead = 0;//记录获取的数据长度
while (true)
{
if (sp != null && sp.IsOpen)
{
try
{
bytesToRead = sp.Read(dataBytes, 0, dataBytes.Length);
for (int i = 0; i < bytesToRead; i++)
{
list.Add(dataBytes[i]);
}
}
catch (System.Exception ex)
{
Debug.Log(ex.ToString());
}
}
Thread.Sleep(1);//50
}
}
/// <summary>
/// 释放
/// </summary>
public void m_clear()
{
if (sp.IsOpen)
sp.Close();
if (tm != null)
tm.Cancel();
if (thread.IsAlive)
thread.Abort();
}
}