DACManager.cs 11.9 KB
using log4net;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TSA_V.Common;

namespace TSA_V.DeviceLibrary
{
    public class DACBean
    {
        private double minX = ConfigAppSettings.GetDoubleValue(Setting_Init.XAxis_MinValue);
        private double maxX = ConfigAppSettings.GetDoubleValue(Setting_Init.XAxis_MaxValue);
        public  readonly ILog LOGGER = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private  AcSerialBean bean = null;
        public  bool isRun = false;
        public string PortName = "";
        public  string LastMsg = "";
        #region 串口操作
        public int SpeedTimer = ConfigAppSettings.GetIntValue(Setting_Init.SpeedTimer);
        public  bool InitPort(string comPortName)
        {
            PortName = comPortName;
            InitWorkTimer();
            //串口参数设置:19200波特率,8数据位,1停止位,无校验位。
            if (isRun)
            {
                return true;
            }
            int baduRaate = 19200;
            int parity = 0;
            int dataBits = 8;
            StopBits bits = StopBits.One;
            return InitPort(comPortName, baduRaate, parity, dataBits, bits);
        } 
        private  bool InitPort(string comPortName, int baudRate, int tparity, int dataBits, StopBits stopBits)
        { 
            InitWorkTimer();
            if (isRun)
            {
                return true;
            }
            try
            {
                Parity parity = (Parity)tparity;
                bean = new AcSerialBean(comPortName, baudRate, parity, 8, stopBits);
                bool result = bean.openPort();
                if (!result)
                {
                    return false;
                }

                isRun = true;
            }
            catch (Exception ex)
            {
                isRun = false;
                LogUtil.error(LOGGER, "串口【" + comPortName + "】打开DAC控制器串口失败:" + ex.ToString());
                return false;
            }
            return true;
        }
        public  void ClosePort()
        {
            StopAll();
            isRun = false;
            if (bean != null)
            {
                bean.closePort();
            }workTimer.Enabled = false;
            LogUtil.info(LOGGER, "串口【" + bean.PortName + "】关闭DAC控制器串口完成");
        }

        public void StopAll()
        {

            listTimer.Enabled = false;
            workTimer.Enabled = false;
        }


        #endregion
        private  void InitWorkTimer()
        {
            if (SpeedTimer <= 0)
            {
                SpeedTimer = 30;
            }
            if (stepValue <= 0)
            {
                stepValue = 0.01;
            }
            workTimer.Interval = SpeedTimer;
            workTimer.AutoReset = true;
            workTimer.Enabled = false;
            workTimer.Elapsed += WorkTimer_Elapsed;
            LogUtil.info("workTimer间隔SpeedTimer:" + SpeedTimer + ",每次步进值StepValue:" + stepValue);
            listTimer.Interval = 300;
            listTimer.AutoReset = true;
            listTimer.Enabled = false;
            listTimer.Elapsed += ListTimer_Elapsed;
        }
        private List<double> targetList = new List<double>();
        private int currIndex = -1;
        private  void ListTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (targetList.Count <= 0)
            {
                listTimer.Enabled = false;
                return;
            }
            if (workTimer.Enabled.Equals(false))
            {
                TimeSpan span = DateTime.Now - lastStopTime;
                if (span.TotalSeconds > 2)
                {
                    currIndex++;
                    if (currIndex < 0 || currIndex >= targetList.Count)
                    {
                        currIndex = 0;
                    }
                    double value = targetList[currIndex];
                    SlowSetVoltage(value);
                }
            }
        }

        public  double TargetVoltage = 0;
        private double stepValue = ConfigAppSettings.GetDoubleValue(Setting_Init. StepValue);
        private  System.Timers.Timer workTimer = new System.Timers.Timer();
        private  System.Timers.Timer listTimer = new System.Timers.Timer();

        private  DateTime lastStopTime = DateTime.Now;
        private  void WorkTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (TargetVoltage.Equals(LastVoltage))
            {
                lastStopTime = DateTime.Now;
                workTimer.Enabled = false;
            }
            else
            {
                if (TargetVoltage > LastVoltage)
                {
                    double value = LastVoltage + stepValue;
                    if (value > TargetVoltage)
                    {
                        value = TargetVoltage;
                    }
                    SendVoltage(value);
                }
                else
                {
                    double value = LastVoltage - stepValue;
                    if (value < TargetVoltage)
                    {
                        value = TargetVoltage;
                    }
                    SendVoltage(value);
                }
            }
        }

       
        public  void StopList()
        {
            workTimer.Stop();
            listTimer.Stop();
        }
        public  void SlowSetVoltageList(List<double > list)
        {
            if (isRun.Equals(false))
            {
                return;
            }
            targetList = new List<double>(list);
            listTimer.Enabled = true;
        }
        public  void SlowSetVoltage(double value)
        {
            if (isRun.Equals(false))
            {
                return;
            }
            workTimer.Enabled = false;
            LogUtil.debug("串口【"+bean.PortName+ "】SlowSetVoltage【" + value + "】");
            TargetVoltage = value;
            workTimer.Enabled = true;
        }
        public  void SetVoltage(double value)
        {
            if (isRun.Equals(false))
            { 
                return;
            }
            workTimer.Enabled = false;
            listTimer.Enabled = false;
            TargetVoltage = value;
            SendVoltage(value);
        }
         
        //数据头+输出电压极性字节+输出电压值个位数字节+输出电压值小数字节+数据尾
        public  double LastVoltage = 0;
        private  void SendVoltage(double value)
        {
            if (isRun.Equals(false))
            {
                return;
            }
            if (value <= minX || value >= maxX)
            {
                LogUtil.error("试图对串口【"+bean.PortName+"】设置电压【"+ value + "】直接返回不处理");
            }
     
            LastVoltage =Math.Round( value,2);
            //数据头固定为:0X5A
            //数据尾固定为:0XA5
            //例如:一次发送的数据类似于这样:5A 01 09 30 A5
            //解释:
            //5A:数据头,为固定字节
            //01:表示输出电压极性,这个位置可以出现00,01,02几个数值,01表示输出正电压,02表示输出负电压,00表示输出0V(可用于0电位点校准)。
            //09 30:电压数值2字节,09 30表示输出9.30V电压。此数值在00 00~09 99之间,表示0.00V~9.99V电压。这个字节四位数字左边的一位数是无效数字,始终为0,比如,09 30,用户输入成19 30,DAC板接收到数据后会去除掉左边的1,仍然输出为09 30(9.3V)。
            //A5:数据尾,为固定字节。
            //综上所述:5A 01 09 30 A5这一帧数据表示DAC板输出+9.30V电压。
            //注意所有发送的数据都是16进制数据(HEX).
            // 板子接受5字节数据后返回2字节DAC数据,以便用户确认通讯正常。例如,发送5A 01 09 30 A5五字节后,返回的2字节数据是09 30
            byte head = 0X5A;
            byte end = 0XA5;
            //1是正方向
            byte fangxiang = 0x01;
            if (value < 0)
            {
                fangxiang = 0x02;

            }
            else if (value.Equals(0))
            {
                fangxiang = 0x00;
            }
            int zhengshu =Math.Abs( (int)(value/1));
            int xiaoshu =(int)Math.Abs( value  * 100 % 100);
            byte[] sendData = new byte[5];
            sendData[0] = head;
            sendData[1] = fangxiang;
            sendData[2] = Convert.ToByte(Convert.ToInt32(zhengshu.ToString(), 16));
            sendData[3] = Convert.ToByte(Convert.ToInt32( xiaoshu.ToString(),16));
            sendData[4] = end;
          
            SendData(sendData);
        }

        private  byte[] WriteData(int slvAddr, byte cmd, byte dataLength, int dataValue)
        {
            byte[] sendData = new byte[5 + dataLength];
            sendData[0] = (byte)slvAddr;
            sendData[1] = cmd;
            sendData[2] = dataLength;
            if (dataLength.Equals(0x00))
            {
            }
            else if (dataLength.Equals(0x01))
            {
                sendData[3] = (byte)dataValue;
            }
            else if (dataLength.Equals(0x04))
            {
                sendData[3] = 0x00;
                sendData[4] = 0x00;
                sendData[5] = 0x00;
                sendData[6] = 0x00;
                string speed = Convert.ToString(dataValue, 16);
                byte[] speedByte = SerialBean.StringToByte(speed);

                for (int i = 0; i < speedByte.Length; i++)
                {
                    if (i >= 4)
                    {
                        break;
                    }
                    sendData[6 - (speedByte.Length - 1 - i)] = speedByte[i];
                }
            }
            sendData = buildCheckData(sendData, 3 + dataLength);
            SendData(sendData);
            return sendData;
        }
        private  byte[] buildCheckData(byte[] sendData, int length)
        {
            ushort pChecksum = 0;
            SerialBean.CalculateCRC(sendData, length, out pChecksum);
            string checkStr = Convert.ToString(pChecksum, 16);
            byte[] checkByte = SerialBean.StringToByte(checkStr);
            if (checkByte.Length == 1)
            {
                sendData[length] = checkByte[0];
                sendData[length + 1] = 0x00;
            }
            else
            {
                sendData[length + 1] = checkByte[0];
                sendData[length] = checkByte[1];
            }
            return sendData;
        }
        private byte[] SendData(byte[] data)
        {
            string strSend = "";
            for (int i = 0; i < data.Length; i++)
            {
                strSend += string.Format("{0:X2} ", data[i]);
            }
            if (strSend.Equals(""))
            {
                return null;
            }
            if (!isRun)
            {
                LogUtil.error(LOGGER, "DAC串口【" + bean.PortName + "】发送数据【" + strSend + "】,当前串口未连接上,发送失败!");
                return null;
            }
            LogUtil.debug(LOGGER, "DAC串口【" + bean.PortName + "】发送数据【" + strSend + "】");
            byte[] reviceByte = null;
            bean.SendCommand(data, ref reviceByte, 100, 2);
            if (reviceByte != null)
            {
                string reviceData = "";
                for (int i = 0; i < reviceByte.Length; i++)
                {
                    reviceData += string.Format("{0:X2} ", reviceByte[i]);
                }
                LogUtil.debug(LOGGER, "DAC串口【" + bean.PortName + "】收到数据【" + reviceData + "】");
            }
            return reviceByte;
        }
    }
}