Ocean Optics 사의 OmniDriver 제어코드 - C#

Software/C#|2023. 2. 17. 09:27
반응형

Ocean Optics 사의 스펙트로메타 사용을 위해 제공되는 OmniDriver 를 C#으로 제어하기 위한 코드 입니다. OmniDriver 의 경우 JAVA 로 개발되었고 타 언어에서는 이것을 사용하기 위해 Wrapper 용 DLL 을 별도로 제공합니다. 

 

1. OmniDriver 를 설치하시면 C:\Program Files\Ocean Optics\OmniDriverSPAM\OOI_HOME 폴더에 NETOmniDriver-NET40.DLL 파일이 있습니다. 이 파일을 참조로 추가하신 후 사용하면 됩니다. 

   * 참고로 OmniDriver 설치 후 제공되는 매뉴얼에는 NETOmniDriver.DLL 이라고 명시되어 있는데 이 파일이 아니고 위에 써 있는 파일입니다.

   * 또한 참조 추가시에 프로젝트 참조로 하시지 마시고 COM 참조에서 찾아 보기를 통해 해당 파일을 찾아서 등록하셔야 합니다. 

Omni Driver 참조 추가 방법
Omni Driver 참조 추가 방법

2. 위에 처럼 등록하시면 솔루션 탐색기에서는 아래와 같이 종속성의 어셈블리안에 등록이 됩니다. 이렇게 참조추가가 안돼고 다른 위치에 등록이 되면 사용이 안돼더라고요.

OmniDriver 참조 추가
OmniDriver 참조 추가

3. 아래는 OmniDriver 를 제어하기 위한 클래스 코드 입니다. 

   * 이 클래스의 경우 한개의 SpectroMeter 를 사용하는 전제로 코드를 만들었습니다.

   * 여러개의 SpectroMeter 를 사용할 경우 코드를 수정해서 사용하시든 아니면 아래 클래스를 사용하고 객체를

      SpectroMeter 갯수 만큼 만들어 사용하시면 되겠습니다. 

using OmniDriver;

namespace OmniDriver
{
    public struct CalData
    {
        public double IntegTime = 1000;     // unit = [usec]
        public double[] dark;
        public double[] Reference;

        public CalData(int PixelCount)
        {
            dark = new double[PixelCount];
            Reference = new double[PixelCount];
        }
    }
    //-------------------------------------------------------------------------------------------------------
    public struct SpectroMeterParams
    {
        public int IntegrationTime { get; set; } = 1000;    // unit = [usec]
        public int BoxcarWidth { get; set; } = 3;
        public int ScansToAverage { get; set; } = 2;
        public int CorrectForElectricalDark { get; set; } = 0;   // 전기적 노이즈 제거 여부 : 0 or 1 
        public SpectroMeterParams() { }
        public SpectroMeterParams(int IntegTime, int BoxcarWidth, int ScanToAverage, int CorrectForElectricalDark)
        {
            this.IntegrationTime = IntegTime;
            this.BoxcarWidth = BoxcarWidth;
            this.ScansToAverage = ScanToAverage;
            this.CorrectForElectricalDark = CorrectForElectricalDark;
        }
    }
    //-------------------------------------------------------------------------------------------------------
    public class CSpectroMeter
    {
        private readonly OmniDriver.NETWrapper Wrapper;
        private readonly int Index;
        private CalData CalibrationData;

        private int _PixelCount;
        public int PixelCount { get { return _PixelCount; } }
        public string Serial { get { return Wrapper.getSerialNumber(Index); } }
        public int IntegrationTime
        {
            set { Wrapper.setIntegrationTime(Index, value); }
            get { return Wrapper.getIntegrationTime(Index); }
        }
        public int BoxcarWidth
        {
            set { Wrapper.setBoxcarWidth(Index, value); }
            get { return Wrapper.getBoxcarWidth(Index); }
        }
        public int ScansToAverage
        {
            set { Wrapper.setScansToAverage(Index, value); }
            get { return Wrapper.getScansToAverage(Index); }
        }
        public int CorrectForElectricalDark
        {
            set { Wrapper.setCorrectForElectricalDark(Index, value); }
            get { return Wrapper.getCorrectForElectricalDark(Index); }
        }
        public CSpectroMeter() 
        {
            Wrapper = new OmniDriver.NETWrapper();
            Index = 0;
        }
        //---------------------------------------------------------------------------------------------------
        public CSpectroMeter(OmniDriver.NETWrapper wrapper, int index)
        {
            this.Wrapper = wrapper;
            this.Index = index;
        }
        //---------------------------------------------------------------------------------------------------
        public string getSerialNumber()
        {
            var serial = Wrapper.getSerialNumber(Index);
            return serial;
        }
        //---------------------------------------------------------------------------------------------------
        public bool connect()
        {
            bool result = false;

            var count = Wrapper.openAllSpectrometers();
            if (count >= 0)
            {
                result = true;
                _PixelCount = Wrapper.getNumberOfDarkPixels(Index);
                CalibrationData = new CalData(_PixelCount);
            }

            return result;
        }
        //---------------------------------------------------------------------------------------------------
        public void getSpectrum(ref double[] Wavelength, ref double[] Spectrum)
        {
            Spectrum = Wrapper.getSpectrum(Index);        // 스펙트로메타에서 측정된 RAW Intensity 값 (Y 축)
            Wavelength = Wrapper.getWavelengths(Index);   // 스펙트로메타의 파장 데이타 (X 축)
        }
        //---------------------------------------------------------------------------------------------------
        public void getIrradianceData(ref double[] Wavelength, ref double[] Irradiance)
        {
            getSpectrum(ref Wavelength, ref Irradiance);

            for(int loop=0; loop < Irradiance.Length; loop++) 
            {
                if (Params.CorrectForElectricalDark == 0) Irradiance[loop] = Irradiance[loop] - CalibrationData.dark[loop];

                Irradiance[loop] = (Irradiance[loop] * CalibrationData.Reference[loop]) * (Params.IntegrationTime / CalibrationData.IntegTime);
            }
        }
        //---------------------------------------------------------------------------------------------------
        public void setSpectrometerParams(SpectroMeterParams Params)
        {
            Wrapper.setIntegrationTime(Index, Params.IntegrationTime);
            Wrapper.setScansToAverage(Index, Params.ScansToAverage);
            Wrapper.setBoxcarWidth(Index, Params.BoxcarWidth);
            Wrapper.setCorrectForElectricalDark(Index, Params.CorrectForElectricalDark);
        }
        //---------------------------------------------------------------------------------------------------
        public void close()
        {
            Wrapper.closeSpectrometer(Index);
        }
        //---------------------------------------------------------------------------------------------------
        public virtual bool readCalibrationFile(string filename) 
        {
            bool result = true;

            if (!File.Exists(filename)) result = false;
            else
            {
                using (StreamReader sr = new StreamReader(filename))
                {
                    int index = 0;
                    string[] split;
                    string line;

                    line = sr.ReadLine();  // Integration Time of reference sample
                    if (line is not null)
                    {
                        split = line.Split(',');
                        CalibrationData.IntegTime = double.Parse(split[1]);
                    }

                    sr.ReadLine();  // Header

                    while ((line = sr.ReadLine()) != null)
                    {
                        split = line.Split(',');
                        CalibrationData.dark[index] = double.Parse(split[1]);
                        CalibrationData.Reference[index] = double.Parse(split[2]);

                        index++;
                    }
                }
            }

            return result;
        }
        //---------------------------------------------------------------------------------------------------
    }
}
반응형

댓글()