DauxiKS107Controller.cs 7.0 KB
using OnlineStore.Common;
using OnlineStore;
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;

namespace DeviceLibrary
{

    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;
            _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))
                {
                    LogUtil.info($"{comPortName}读取到声波距离:{value}mm,err:{errmsg}");
                    readok = true;
                    if (value > 0 && value < 1000)
                    {
                        //Distance = value;
                        lock (distantlist)
                        {
                            distantlist.Add(value);
                            if (distantlist.Count > 8)
                            {
                                distantlist.RemoveAt(0);
                            }
                            Distance = TrimMean(distantlist, 0.8);
                        }
                        return;
                    }
                    else
                        readok = false;
                }
                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)
            {
                try
                {
                    _serialPort = new SerialPort(comPortName, baudRate, parity, dataBits, stopBits);
                    _serialPort.RtsEnable = true;  //自动请求
                    _serialPort.ReadTimeout = 100;//超时
                    LogUtil.info("声波传感器" + comPortName + "打开成功");
                }
                catch (Exception e)
                {
                    errmsg += crc.GetString("comOpenFail", "串口{0}打开失败", _comport);
                    LogUtil.info("串口"+_comport+"打开失败:" + e.ToString());
                    return false;
                }
            }
            //errmsg += crc.GetString("Res0095.e19bb66e", "初始化.");
            if (_serialPort.IsOpen)
                _serialPort.Close();

            bool ok = false;

            try
            {
                //打开串口
                //errmsg += $"打开串口:{comPortName}.";
                _serialPort.Open();

                LogUtil.info(_comport + "声波传感器端口打开成功"  );
                Thread.Sleep(200);
                for (int i = 1; i < 10; i++)
                {
                    Thread.Sleep(100);
                    //errmsg += crc.GetString("Res0096.184519ba", "检测数据.");
                    Quary(out int value, out string err);
                    //errmsg += err;
                    LogUtil.info(_comport + "声波传感器检测数据结果:"+value+"/" + err);
                    if (value > 0)
                    {
                        timer.Enabled = true;
                        ok = true;
                        break;
                    }
                }
            }
            catch (Exception Ex)
            {
                errmsg += Ex.ToString();
                //throw Ex;
            }
            return ok;
        }
        public bool PortIsOpen()
        {
            return (_serialPort != null) && (_serialPort.IsOpen);
        }

        public bool ClosePort()
        {
            if(_serialPort!=null&&_serialPort.IsOpen)
            {
                _serialPort.Close();
                
            }
            return true;
        }
        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(80);
                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 += crc.GetString("comDataError", "串口{0}数据错误{1}", _serialPort.PortName, BitConverter.ToString(buf));
                    LogUtil.error( $"{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(0);
                templist.RemoveAt(templist.Count - 1);
                templist.RemoveAt(templist.Count - 1);
                return (int)templist.Average();
            }
            catch (Exception ex)
            {
                LogUtil.error(ex.ToString());
                return 0;
            }
        }
    }
}