DauxiKS107Controller.cs 5.0 KB
using OnlineStore.Common;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

public class DauxiKS107Controller
{
    private static int baudRate = 9600;//波特率
    private static Parity parity = Parity.None;//校验位
    private static int dataBits = 8;//数据位
    private static StopBits stopBits = StopBits.One; //停止位

    private SerialPort _serialPort = null;
    string comPortName;
    System.Timers.Timer timer;
    public volatile int Distance;
    public bool IsRunning { get => timer.Enabled; }
    public DauxiKS107Controller(int Elapsms=5000)
    {
        timer = new System.Timers.Timer(Elapsms);
        timer.Elapsed += Timer_Elapsed;
        timer.AutoReset = true;
        timer.Enabled = false;
    }
    ~DauxiKS107Controller() {
        LogUtil.info($"{comPortName}液位传感器退出");
        timer.Enabled = false;
        if (_serialPort != null) {
            _serialPort.Close();
        }
    }
    List<int> distantlist=new List<int>() { 1000, 100, 100, 100, 10 };
    private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        bool readok = true;
        for (int i = 0; i < 5; i++)
        {
            if (Quary(out int value, out string errmsg))
            {
                Debug.WriteLine($"{comPortName}读取到液位:{value}mm,err:{errmsg}");
                readok = true;
                if (value > 0 && value<500)
                {
                    //Distance = value;
                    lock (distantlist)
                    {
                        distantlist.Add(value);
                        if (distantlist.Count > 5)
                        {
                            distantlist.RemoveAt(0);
                        }
                        Distance= TrimMean(distantlist, 0.8);
                    }
                    return;
                }
            }
            else {
                readok = false;
            }
        }
        if (!readok)
        {
            LogUtil.info($"{comPortName}液位传感器读取失败,重新打开");
            if (!OpenPort(comPortName, out string errmsg)) {
                LogUtil.info($"{comPortName}液位传感器打开失败:"+ errmsg);
            }
        }
    }
    
    /// <summary> 
    /// 打开串口资源 
    /// <returns>返回bool类型</returns>  
    /// </summary> 
    public bool OpenPort(string _comport,out string errmsg)
    {

        comPortName = _comport;
        //如果串口是打开的,先关闭 
        errmsg = "";
        if (_serialPort == null)
        {
            _serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits);
            _serialPort.RtsEnable = true;  //自动请求
            _serialPort.ReadTimeout = 100;//超时
        }
        errmsg += "初始化.";
        if (_serialPort.IsOpen)
            _serialPort.Close();
        
        bool ok = false;

        try
        {
            //打开串口
            errmsg += "打开串口.";
            _serialPort.Open();
            
            for (int i = 1; i < 10; i++) {
                Thread.Sleep(100);
                errmsg += "检测数据.";
                Quary(out int value, out string err);
                errmsg += err;
                if (value > 0)
                {
                    timer.Enabled = true;
                    ok = true;
                    break;
                }
            }
        }
        catch (Exception Ex)
        {
            errmsg = Ex.ToString();
            //throw Ex;
        }
        return ok;
    }
    static byte[] quarycommand = new byte[] { 0xe8, 0x02, 0xb0 };
    public bool Quary(out int value, out string errmsg) {
        errmsg = "";
        byte[] buf = new byte[8];
        value = 0;
        try
        {
            _serialPort.Write(quarycommand, 0, quarycommand.Length);
            Thread.Sleep(10);
            var readlen = _serialPort.Read(buf, 0, buf.Length);
            if (readlen >= 2)
            {
                var c = new byte[] { buf[1], buf[0] };
                value = (int)BitConverter.ToUInt16(c, 0);
            }
            else
            {
                errmsg = $"{comPortName}返回数据不正确:" + BitConverter.ToString(buf);
                return false;
            }
        }
        catch (Exception ex){
            errmsg = ex.ToString();
            return false;
        }
        return true;
    }

    public static int TrimMean(List<int> array, double percent)
    {
        try
        {
            if (array.Count < 4)
            {
                return array[0];
            }
            List<int> templist = new List<int>(array);
            templist.Sort();
            templist.RemoveAt(0);
            templist.RemoveAt(templist.Count - 1);
            return (int)templist.Average();
        }catch (Exception ex)
        {
            LogUtil.error(ex.ToString());
            return 0;
        }
    }
}