每台设备的解析方式都有区别,此代码仅为解析RS485测速仪器(modbus协议)
/// <summary>
/// 速度测量仪器
/// </summary>
public class RS485Manager
{
private static RS485Manager instance;
public static RS485Manager Instance
{
get
{
if (instance == null)
{
instance = new RS485Manager();
}
return instance;
}
}
private SerialPort serialPort;
private Timer timer;
/// <summary>
/// 当前速度
/// </summary>
public double Speed { get; private set; }
/// <summary>
/// 上一圈
/// </summary>
private float PreLaps;
/// <summary>
/// 当前圈数
/// </summary>
public float CurrentLaps { get; private set; }
/// <summary>
/// 半径
/// </summary>
private double Radius{ get; set; }
public RS485Manager()
{
serialPort = new SerialPort();
serialPort.BaudRate = 9600;
serialPort.DataBits = 8;
serialPort.StopBits = StopBits.One;
serialPort.Parity = Parity.None;
serialPort.PortName = ConfigurationManager.AppSettings["PortName"];
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
timer = new Timer();
timer.Interval = 1000;
timer.Tick += Timer_Tick;
Radius = Convert.ToDouble(ConfigurationManager.AppSettings["Radius"]);
}
/// <summary>
/// 开始运行
/// </summary>
public void Start()
{
if (!serialPort.IsOpen)
serialPort.Open();
timer.Start();
}
/// <summary>
/// 停止运行
/// </summary>
public void Stop()
{
if (serialPort.IsOpen)
serialPort.Close();
timer.Stop();
}
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(500);
try
{
byte[] respBytes = new byte[serialPort.BytesToRead];
serialPort.Read(respBytes, 0, respBytes.Length);
List<byte> respList = new List<byte>(respBytes);
respList.RemoveRange(0, 3);
respList.RemoveRange(respList.Count - 2, 2);
if (respList.Count != 4) return;
int result = 0;
for (int i = 0; i < respList.Count; i++)
{
if (i != respList.Count - 1)
result += respList[i] * (int)Math.Pow(256, respList.Count - i - 1);
else
result += respList[i];
}
float r = result / 100f;
CurrentLaps = r;
GetSpeed();
if (result >= 900000)
{
ResetRS485();
}
}
catch (Exception)
{
}
}
private void Timer_Tick(object sender, EventArgs e)
{
SendDataRS485();
}
/// <summary>
/// 发送读取上排数据指令
/// </summary>
private void SendDataRS485()
{
byte[] data = StringToHexByte("01 03 00 21 00 02 94 01");
serialPort.Write(data, 0, 8);
}
/// <summary>
/// 发送清零指令
/// </summary>
private void ResetRS485()
{
byte[] data = StringToHexByte("01 06 00 00 00 02 08 0B");
serialPort.Write(data, 0, 8);
CurrentLaps = 0;
PreLaps = 0;
}
/// <summary>
/// 获取速度
/// </summary>
private void GetSpeed()
{
if (CurrentLaps != 0 && PreLaps != 0)
{
var laps = (CurrentLaps - PreLaps) / 4;//4个数字是一圈
var circumference = 2 * Radius * Math.PI;//周长
var speed = laps * circumference / 1;//当前1秒执行一次
if (Math.Abs(speed) < 10)
Speed = speed;
}
PreLaps = CurrentLaps;
}
public static byte[] StringToHexByte(string hexString)
{
hexString = hexString.Replace(" ", "");
if (hexString.Length % 2 != 0)
hexString += " ";
var returnBytes = new byte[hexString.Length / 2];
for (var i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return returnBytes;
}
}