<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>제어와 계측</title>
    <link>https://auto-control.tistory.com/</link>
    <description>장비제어와 계측에 관련된 알고리즘 및 소스 코드를 공유하기 위한 사이트입니다. </description>
    <language>ko</language>
    <pubDate>Fri, 12 Jun 2026 20:46:20 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>sihwankim</managingEditor>
    <image>
      <title>제어와 계측</title>
      <url>https://tistory1.daumcdn.net/tistory/5896611/attach/67f361b3e1a041b8a5ccdfac017d6d4a</url>
      <link>https://auto-control.tistory.com</link>
    </image>
    <item>
      <title>.net MAUI 에서 앱 아이콘 변경 방법</title>
      <link>https://auto-control.tistory.com/94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 앱을 만들기 위해 MAUI를 이용해서 만들었습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱을 만들고 나서 아이콘을 변경하기 위해 인터넷에 돌아 다니는 방법을 사용해서 변경했는데 왠지 기본 아이콘에서 전혀 변경이 안돼어서 몇일을 찾고 찾아서 드디어 해결을 했습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;솔루션 탐색기에서 Platforms&amp;rarr;Android&amp;rarr;Resources&amp;rarr;AndroidManifest.xml 파일을 클릭하면&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;애플리케이션 세부정보가 나타납니다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;애플리케이션 아이콘 항목을 아래와 같이 변경을 해 주어야만 아이콘이 변경이 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cf8vun/dJMcaaX4cNG/lUgOVtF5GR6dFdUsDNtSk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cf8vun/dJMcaaX4cNG/lUgOVtF5GR6dFdUsDNtSk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cf8vun/dJMcaaX4cNG/lUgOVtF5GR6dFdUsDNtSk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcf8vun%2FdJMcaaX4cNG%2FlUgOVtF5GR6dFdUsDNtSk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;690&quot; height=&quot;42&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Resources&amp;rarr;AppIcon 위치에 원하는 이미지를 넣습니다. (예 : Icon.png)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그런후 프로젝트 파일을 엽니다. (확장자 : csproj)&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아래 내용을 추가 합니다.&lt;/p&gt;
&lt;pre class=&quot;xml&quot; style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;&lt;code&gt;&amp;lt;!-- App Icon --&amp;gt;
	&amp;lt;MauiIcon Include=&quot;Resources\AppIcon\appicon.svg&quot; ForegroundFile=&quot;Resources\AppIcon\icon.png&quot; Color=&quot;#FFFFFF&quot; /&amp;gt;

그리고 다시 컴파일후에 실행하면 아이콘이 변경이 됩니다. &lt;/code&gt;&lt;/pre&gt;</description>
      <category>Software/C#</category>
      <author>sihwankim</author>
      <guid isPermaLink="true">https://auto-control.tistory.com/94</guid>
      <comments>https://auto-control.tistory.com/94#entry94comment</comments>
      <pubDate>Tue, 2 Dec 2025 14:04:12 +0900</pubDate>
    </item>
    <item>
      <title>IEEE754 단정밀(32Bit) 데이타와 float 형 변수의 상호 변환 - C#</title>
      <link>https://auto-control.tistory.com/93</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1743394743638&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;static class Ieee754Converter
{
    public static byte[] GetBytes(float value)
    {
        byte[] bytes = BitConverter.GetBytes(value);
        return bytes;
    }
    public static float ToSingle(byte[] bytes)
    {
        float value = BitConverter.ToSingle(bytes, 0);
        return value;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;예 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;+7.282600E+01 &amp;nbsp;&amp;lt;-&amp;gt; {0xE9} {0xA6} {0x91} {0x42}&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;byte[ ] temp = Ieee754Converter.GetBytes(3.141592f);&lt;br /&gt;float value = Ieee754Converter.ToSingle(temp);&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;</description>
      <category>Software/C#</category>
      <category>ieee754</category>
      <author>sihwankim</author>
      <guid isPermaLink="true">https://auto-control.tistory.com/93</guid>
      <comments>https://auto-control.tistory.com/93#entry93comment</comments>
      <pubDate>Mon, 31 Mar 2025 13:22:32 +0900</pubDate>
    </item>
    <item>
      <title>Laser Diode의 Threshold Current 계산 알고리즘 - Least Square Method - C#</title>
      <link>https://auto-control.tistory.com/92</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1742790281428&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;	public double ThresholdCurrent(in double[] Current, in double[] Power, double PowerLow, double PowerHigh)
	{
		double thresholdCurrent = 0;

		try
		{
			int startIndex = Array.FindIndex(Power, x =&amp;gt; x &amp;gt;= PowerLow);
			int endIndex = Array.FindIndex(Power, x =&amp;gt; x &amp;gt;= PowerHigh);

			var subCurrent = Current.Skip(startIndex).Take(endIndex - startIndex + 1).ToArray();
			var subPower = Power.Skip(startIndex).Take(endIndex - startIndex + 1).ToArray();

			var (slope, intercept) = LeastSquaresFit(subCurrent, subPower);

			if(slope != 0) thresholdCurrent = -intercept / slope;            
		}
		catch
		{
			thresholdCurrent = 0 ;
		}		

		return thresholdCurrent;
	}	
	//-----------------------------------------------------------------------------------------------------------------
	private (double Slope, double Intercept) LeastSquaresFit(double[] x, double[] y)
	{
		int n = x.Length;        
        
        double sumX = x.Sum();
        double sumY = y.Sum();
        double sumXY = x.Zip(y, (xi, yi) =&amp;gt; xi * yi).Sum();
        double sumXX = x.Select(xi =&amp;gt; xi * xi).Sum();
        
        var Slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);
        var yIntercept = (sumY - slope * sumX) / n;
		
		return (slope, yIntercept);
	}
	//-----------------------------------------------------------------------------------------------------------------&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Characteristics Data/LD(Laser Diode)</category>
      <author>sihwankim</author>
      <guid isPermaLink="true">https://auto-control.tistory.com/92</guid>
      <comments>https://auto-control.tistory.com/92#entry92comment</comments>
      <pubDate>Mon, 24 Mar 2025 13:25:36 +0900</pubDate>
    </item>
    <item>
      <title>비주얼 스튜디오(Visual Studio) WinForm 에서 폼 디자이너가 나타나지 않을 때</title>
      <link>https://auto-control.tistory.com/91</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;비주얼 스튜디오로 만든 Winform 프로젝트를 수정할 일이 생겨서 프로젝트를 열었는데 폼 디자이너가 전혀 열리지 않는 현상이 발생했다. 인터넷을 뒤져서 이것저것 찾아 보았지만 해결을 할 수가 없었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;그러다 우연히 프로젝트가 들어있는 폴더를 밖으로 빼고 다시 불러와 보니 정상적으로 폼 디자이너가 보이기 시작했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;원인은 이번에 비주얼 스튜디오가 업그레이드 되면서 프로젝트 파일들이 들어있는 폴더에 ( ) 를 사용했을 경우 문제가 발생한다는 것을 알아냈다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;난 프로그램 버젼을 폴더에 () 안에 표시하는데 그걸 빼고 했더니 정상 동작이 되었다. 이게 오류인지 일부러 그렇게 만든건지 모르겠다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;하여간 아래 처럼 ( ) 제외해야 폼 디자이너가 정상적으로 나타난다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;기존 폴더 : D:\TestProject(Ver 1.0.0)\&amp;nbsp; &amp;nbsp;오류&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;수정 폴더 : D:\TestProject\&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 정상&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Developer's Story</category>
      <author>sihwankim</author>
      <guid isPermaLink="true">https://auto-control.tistory.com/91</guid>
      <comments>https://auto-control.tistory.com/91#entry91comment</comments>
      <pubDate>Thu, 20 Mar 2025 15:35:09 +0900</pubDate>
    </item>
    <item>
      <title>IEEE754 단정밀(32Bit) 데이타와 float 형 변수의 상호 변환 - C++</title>
      <link>https://auto-control.tistory.com/90</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;계측기와 데이타를 주고 받는 경우 계측기에서 측정된 데이타가 ASCii 형태로 들어 오는 경우가 있다. 이럴 경우 데이타의 갯수가 짧은 경우에는 상관이 없지만 데이타 갯수가 수십 ~ 수백개가 될 경우 통신 속도문제로 데이타를 주고 받는데 시간이 많이 걸리게 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;더군다나 ASCii 를 사용하게 되면 데이타는 더 길어질 수 밖에 없어서 시간이 더 많이 소요가 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;이럴때 데이타의 길이를 줄이기 위해 계측기가 IEEE754형태의 단정밀로 변환해서 데이타를 주고 받을 수 있는 경우가 있는데 이럴경우 데이타의 길이를 1/3로 줄일 수 있다. (13byte 아스키값을 4byte 로 변형)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;예 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;+7.282600E+01 &amp;nbsp;&amp;lt;-&amp;gt; {0xE9} {0xA6} {0x91} {0x42}&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;변환 방법은 간단하게 Union 사용하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;union IEEE754_Float&lt;br /&gt;{ &lt;br /&gt;&amp;nbsp; &amp;nbsp; unsigned char uData[4] ; &lt;br /&gt;&amp;nbsp; &amp;nbsp; float fValue ; &lt;br /&gt;}&amp;nbsp;;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;IEEE754_Float data ;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;data.fValue = 72.826 ;&amp;nbsp; &amp;nbsp; &amp;nbsp;// float 변수에 값을 넣으면 uData에 각각의 바이트로 자동으로 변환되어 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;IEEE754_Float data ;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;data. uData[0] = 0xE9 ;&amp;nbsp; // 각 바이트에 값을 넣으면 fValue 에 자동으로 변환된 float 값이 저장된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;data.&lt;span&gt;&amp;nbsp;&lt;/span&gt;uData[1] = 0xA6 ;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;data.&lt;span&gt;&amp;nbsp;&lt;/span&gt;uData[2] = 0x91 ;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;data.&lt;span&gt;&amp;nbsp;&lt;/span&gt;uData[3] = 0x42 ;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Software/C++ Builder</category>
      <author>sihwankim</author>
      <guid isPermaLink="true">https://auto-control.tistory.com/90</guid>
      <comments>https://auto-control.tistory.com/90#entry90comment</comments>
      <pubDate>Mon, 17 Mar 2025 16:05:29 +0900</pubDate>
    </item>
    <item>
      <title>YAML 로 프로그램 설정 데이타 저장 및 불러오기 - C#</title>
      <link>https://auto-control.tistory.com/89</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;이전에 JSON을 이용하여 제어프로그램의 Recipe 파일의 저장과 불러오기 기능에 대해 포스팅 했었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;그런데 조금 사용하기 불편하고 코딩량이 많아서 다른 수단을 찾다가 YAML 이 최근에 설정파일 저장용으로 많이 사용된다는 것을 보고 사용해 보았다. 코딩량도 상당히 줄었고 무엇보다 항목을 추가하거나 제거할 때 코딩에서 수정해야 하는 부분이 많이 줄어서 현재 모든 프로그램에서 사용하고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;1. YAML 사용하기 위해 Nuget에서 YamlDotNet 을 먼저 설치한다.&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;2. Yaml 데이타를 저장하거나 불러오기 위한 클래스 생성 : 다양한 종류의 설정항목에 대응하기 위해 generic class 형식으로 만듦&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741912860103&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class YamlControl&amp;lt;T&amp;gt;
{ 
    public bool SaveYaml(string FileName, T data)
    {
        bool result = true;

        try
        {
            var serializer = new SerializerBuilder().Build().Serialize(data);

            using StreamWriter sw = new StreamWriter(FileName);
            sw.Write(serializer);
        }
        catch
        {
            result = false;    
        }

        return result;
    }

    public bool LoadYaml(string FileName, ref T objectData)
    {
        bool result = true;

        try
        {
            var yaml = File.ReadAllText(FileName);
            objectData = new DeserializerBuilder().Build().Deserialize&amp;lt;T&amp;gt;(yaml);
        }
        catch
        {
            result = false;
        }            

        return result;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;3. 설정항목에 대한 클래스 생성 : 아래 클래스는 프로그램에 따라 변경해야 하며 아래 내용은 예시적으로 만든 임의의 클래스&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741913249557&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class RecipeInform
{
    public BurnInParam burnInParam = new BurnInParam();
    public SweepMeasParam sweepMeasParam = new SweepMeasParam();

    public class BurnInParam
    {
        public bool Measurement { get; set; }
        public double Bias { get; set; }
        public double Step { get; set; }
    }
    
    public class SweepMeasParam
    {
        public double StartCurrent { get; set; }
        public double StopCurrent { get; set; }
        public double StepCurrent { get; set; }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;4. 사용방법&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1741914325690&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;항목 불러오기 

YamlControl&amp;lt;RecipeInform&amp;gt; yamlControl = new YamlControl&amp;lt;RecipeInform&amp;gt;();
string filename = string.Format(&quot;{0}{1}.yaml&quot;, Global.conditionFolder, comboCondition.Text);
RecipeInform recipe = new RecipeInform();
yamlControl.LoadYaml(filename, ref recipe);


항목 저장하기 

RecipeInform recipe = new RecipeInform();
recipe.burnInParam.Measurement = checkBurnInMeas.Checked;
recipe.burnInParam.Bias = double.Parse(textBiasCurrent.Text);
recipe.burnInParam.Step = double.Parse(textBurnInStepCurrent.Text);
recipe.sweepMeasParam.StartCurrent = double.Parse(textStartCurrent.Text);
recipe.sweepMeasParam.StopCurrent = double.Parse(textStopCurrent.Text);
recipe.sweepMeasParam.StepCurrent = double.Parse(textStepCurrent.Text);


string filename = string.Format(&quot;{0}{1}.yaml&quot;, Global.conditionFolder, comboCondition.Text);
YamlControl&amp;lt;RecipeInform&amp;gt; yamlControl = new YamlControl&amp;lt;RecipeInform&amp;gt;();
yamlControl.SaveYaml(filename, recipe) ;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Software/C#</category>
      <author>sihwankim</author>
      <guid isPermaLink="true">https://auto-control.tistory.com/89</guid>
      <comments>https://auto-control.tistory.com/89#entry89comment</comments>
      <pubDate>Fri, 14 Mar 2025 10:07:38 +0900</pubDate>
    </item>
    <item>
      <title>Flow Meter(FML300-D SERIES) 제어 클래스 - C#</title>
      <link>https://auto-control.tistory.com/88</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1741674870024&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    public class FML300 
    {
        private readonly SerialPort commPort ;
        private readonly ModbusSerialMaster modbusSerialMaster ;

        public FML300(ModbusSerialMaster modbusSerial)
        {
            modbusSerialMaster = modbusSerial;
        }
        //---------------------------------------------------------------------------
        public FML300(SerialPort serialPort)
        {
            commPort = serialPort ;
            modbusSerialMaster = ModbusSerialMaster.CreateRtu(commPort) ;
        }
        //---------------------------------------------------------------------------
        public FML300(string portNumber)
        {
            try
            {
                commPort = new SerialPort(portNumber, 38400) ;
                commPort.Parity = Parity.None;
                commPort.StopBits = StopBits.One;
                commPort.ReadTimeout = 100;
                commPort.WriteTimeout = 100;
                commPort.Open();

                modbusSerialMaster = ModbusSerialMaster.CreateRtu(commPort) ;
            }
            catch
            {
            }
        }
        //---------------------------------------------------------------------------
        public bool InstantaneousFlowRate(byte DeviceAddress, ref double FlowRate)
        {
            bool result = true ;

            try
            {
                var buffer = modbusSerialMaster.ReadInputRegisters(DeviceAddress, 3, 1);
                FlowRate = buffer[0] ;
            }
            catch
            {
                result = false ;
            }

            return result ;
        }
        //---------------------------------------------------------------------------
        public bool FlowTemperature(byte DeviceAddress, ref double Temperature)
        {
            bool result = true ;    

            try
            { 
                var buffer = modbusSerialMaster.ReadInputRegisters(DeviceAddress, 4, 1) ;
                Temperature = buffer[0] ;
                if(Temperature &amp;gt; 6000) Temperature = 0;     // 물이 흐르지 않으면 온도가 큰값이 읽혀진다. 
            }
            catch
            {
                result = false ;
            }

            return result ;
        }
        //---------------------------------------------------------------------------
        public int FlowRateAndTemperature(byte DeviceAddress, ref double FlowRate, ref double Temperature)
        {
            int result = 0 ;    

            try
            { 
                var buffer = modbusSerialMaster.ReadInputRegisters(DeviceAddress, 1, 4) ;

                FlowRate = (double)buffer[1] / 100.0 ;
                Temperature = (double)buffer[2] / 10.0 ;

                if(Temperature &amp;gt; 6000) Temperature = 0;     // 물이 흐르지 않으면 온도가 큰값이 읽혀진다. 
            }
            catch
            {
                result = -1 ;
            }

            return result ;
        }
        //---------------------------------------------------------------------------
    }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Software/C#</category>
      <author>sihwankim</author>
      <guid isPermaLink="true">https://auto-control.tistory.com/88</guid>
      <comments>https://auto-control.tistory.com/88#entry88comment</comments>
      <pubDate>Tue, 11 Mar 2025 15:35:59 +0900</pubDate>
    </item>
    <item>
      <title>Chroma IT 의 UPS(Rodem Series) 제어 클래스 - C#</title>
      <link>https://auto-control.tistory.com/87</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1741674571737&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    public class RodemSeries
    {
        private SerialPort commPort;
        public double InputVoltage { get; }
        public double OutputVoltage { get; }
        public double Temperature { get; }
        public int BlackOut { get; }        // 0:No, 1:Yes
	    public int LowBattery { get; }      // 0:No, 1:Yes

        public RodemSeries(SerialPort CommPort)
        {
            commPort = CommPort;
        }
        //---------------------------------------------------------------------------
        public bool Initialize(string ModelName)
        {
            bool result = false ;
	        byte[] sendBuffer = new byte[] {(byte)'I', 0x0d} ;

            try
            {
                commPort.Write(sendBuffer, 0, sendBuffer.Length);
                Thread.Sleep(500);

                if(commPort.BytesToRead &amp;gt; 0)
                {
                    byte[] readBuffer = new byte[commPort.BytesToRead + 5];
                    commPort.Read(readBuffer, 0, commPort.BytesToRead);
                    string str = Encoding.Default.GetString(readBuffer);
                    result = str.Contains(ModelName);
                }
            }
            catch 
            { 
                result = false; 
            }

            return result ;
        }
        //---------------------------------------------------------------------------
        public bool ReadStatus()
        {
            bool result = true;
	        byte[] sendBuffer = new byte[] {(byte)'Q', (byte)'1', 0x0d} ;

            try
            {
                commPort.Write(sendBuffer, 0, sendBuffer.Length);
                Thread.Sleep(500);

                if(commPort.BytesToRead &amp;gt; 0)
                {
                    byte[] readBuffer = new byte[commPort.BytesToRead + 5];
                    commPort.Read(readBuffer, 0, commPort.BytesToRead);

                    if(readBuffer[0] != (byte)'(') result = false;
                    else
                    {
                        result = StatusInformation(readBuffer);    
                    }                    
                }
                else
                {
                    result = false;
                }
            }
            catch 
            { 
                result = false; 
            }

            return result;
        }
        //---------------------------------------------------------------------------
        private bool StatusInformation(byte[] Buffer)
        {
            bool result = true;

            try
            {
                string str = Encoding.Default.GetString(Buffer);
                string[] data = str.Split(' ');

                OutputVoltage = double.Parse(data[2]) ;
                Temperature = double.Parse(data[6]) ;

                BlackOut = Buffer[38] - 0x30;
                LowBattery = Buffer[39] - 0x30;

                if (BlackOut &amp;gt; 1 || BlackOut &amp;lt; 0) BlackOut = 0;
                if (LowBattery &amp;gt; 1 || LowBattery &amp;lt; 0) LowBattery = 0;
            }
            catch
            {
                result = false;
            }

            return result;
        }
        //---------------------------------------------------------------------------
    }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Software/C#</category>
      <author>sihwankim</author>
      <guid isPermaLink="true">https://auto-control.tistory.com/87</guid>
      <comments>https://auto-control.tistory.com/87#entry87comment</comments>
      <pubDate>Tue, 11 Mar 2025 15:32:35 +0900</pubDate>
    </item>
    <item>
      <title>VARIANT 형의 변수를 사용할 때 주의할 점 (C++)</title>
      <link>https://auto-control.tistory.com/86</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;최근 레이저의 광출력을 측정하는 계측기를 사용하는 과정에서 해당 계측기 업체가 제공하는 소스를 그대로 복사해서 함수를 하나 만들어서 사용을 했습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;그런데 이 장비가 번인 장비여서 기본적으로 1000시간 이상 구동을 해야 하는데 200~300 시간 정도 지나면 프로그램이 다운이 되어 버리는 증상이 나타났습니다. 아무리 소스 코드를 봐도 오류를 찾을 수 없었는데 혹시나 해서 계측기 업체가 제공한 소스 코드를 Chat-GPT 에 돌려서 보니 VARIANT 형을 사용하는 과정에서 변수를 Clear 하지 않아서 오버플로우가 발생하는 현상이 있는 것을 찾아 냈습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;아래 함수가 이번에 수정한 부분인데&amp;nbsp; &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;VARIANT value, param1, param2;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 이 세개의 변수가 VARIANT 형으로 선언이 되어 있고 그 중에서 value 변수는 배열 형식으로 데이타를 받아 오도록 되어 있습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;VARIANT 변수가 단일 변수형식일 경우에는 상관 없다고 하는데 배열이나 문자열 같이 데이타가 큰 형식으로 변경이 될 경우에는 반드시 변수를 Clear 해주어야만 메모리 오버플로우가 발생하지 않습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아래 함수를 try finally 구문을 이용해서 함수가 마무리되면&amp;nbsp; VariantClear() 를 이용해서 메모리 해제를 시켜 주었고 이렇게 코드를 수정한 이후에는 프로그램이 다운되지 않고 정상적으로 잘 동작합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;C++ builder 에서는 Variant 라는 형으로 VARIANT 형을 사용하는데 빌더에서 만든 Variant 형은 자동으로 메모리 해제가 되도록 프로그램 되어 있어서 사용자가 메모리 해제를 신경쓰지 않아도 됩니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1741673448339&quot; class=&quot;csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bool __fastcall TAging::readPowerData(const int Channel)
{
	VARIANT value, param1, param2;
	int check = -1 ;
	double Power ;
	bool result = true ;

	try
	{
		try
		{
			check = g_PowerMeter-&amp;gt;GetData(ChannelInformation[Channel].Handle, 0, &amp;amp;value, &amp;amp;param1, &amp;amp;param2) ;

			if(check != 0) result = false ;
			else
			{
				std::vector&amp;lt;double&amp;gt; PowerData = getDoubles(value) ;

				if(PowerData.size() &amp;gt; 0)
				{
					Power = PowerData[0] ;
					Power = (Power * MachineData.PowerCalibration[Channel][0]) + MachineData.PowerCalibration[Channel][1] ;

					ChannelInformation[Channel].MeasData.Power = Power ;
				}
				else
				{
					result = false ;
				}
			}
		}
		catch(...)
		{
			check = -1 ;
			result = false ;
		}
	}
	__finally
	{
		VariantClear(&amp;amp;value);
		VariantClear(&amp;amp;param1);
		VariantClear(&amp;amp;param2);
	}

	return result ;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Software/C++ Builder</category>
      <author>sihwankim</author>
      <guid isPermaLink="true">https://auto-control.tistory.com/86</guid>
      <comments>https://auto-control.tistory.com/86#entry86comment</comments>
      <pubDate>Tue, 11 Mar 2025 15:18:42 +0900</pubDate>
    </item>
    <item>
      <title>소프트웨어 개발에 AI(인공지능)의 활용</title>
      <link>https://auto-control.tistory.com/85</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;최근들어 AI 기술이 발달함에 따라 소프트웨어 개발에도 많이들 AI를 활용하는 방안들에 대한 고민을 하고 있는 것 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;이런 추세에 맞춰서 나 또한 최근에 Chat-GPT 를 많이 활용하기 시작했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;별도로 사용료를 내지 않는 무료버젼을 사용하는데 가끔 새로운 라이브러리나 알고리즘에 대해 Chat-GPT 에게 물어 보면 상당히 좋은 코드를 뽑아내 준다. 최소 몇시간에서 몇일을 자료 찾아가며 만들어야 할 코드를 질문 몇번으로 깔끔하게 만들어 주는 것을 보면 참 세상 많이 좋아졌구나 하는 생각이 든다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;예전에는 개발자 사이트에 찾아 들어가서 QnA 에 올려 놓고 한정없이 답변달리기만 기다리거나 읽기 힘든 원서로된 레퍼런스 자료들을 읽어 가며 코딩을 했었는데 이제는 한글로 질문 몇번만 하면 코드를 척척 뽑아내 준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;한 예로 내 경우 제어프로그램을 하다보니 Recipe 관련 코드를 많이 사용하는데 저장파일을 주로 ini 형식을 주로 사용했었다. 그런데 ini 파일에 단점이 항목이 하나 늘어나면 관련해서 수정해야 할 코드가 4~5 군데나 되다 보니 상당히 귀찮아서 yaml 을 이용한 recipe 관리를 하기위해 관련 라이브러리를 설치하고 yaml 라이브러리를 사용하기 위한 코드를 chat-gpt 에게 요청하니 바로 코드를 만들어 주었고 그 코드를 특별히 수정하지 않고 적용해 보니 잘 동작하였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;또 OpenCV 관련하여 이미지 프로세싱 관련한 코드들도 잘 만들어 주어서 조금만 수정하면 꽤 괞찬은 코드가 생성되기도 했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;한번은 Aging 관련하여 장비를 납품받은 업체에서 프로그램이 자꾸 다운이 된다는 문의가 왔다. 보통 1000시간 이상 돌아 가는 장비라서 중간에 프로그램이 죽어 버리면 상당한 문제가 되었다. 문제를 찾기 위해 코드를 아무리 뒤져 보아도 문제점을 찾을 수가 없었고 프로그램이 보통 200~300시간 잘 돌아가다가 죽어버리는 상황이었기에 현장에서 디버깅을 걸어 놓아도 그 시간동안 기다릴 수가 없으니 원인을 찾기가 매우 힘들었다. 코드를 아무리 보아도 원인을 찾을 수 없어서 마지막 방법으로 Chat-GPT를 이용하 보기로 하고 그래도 의심이 가는 코드들 넣어서 문제점을 물어 보았지만 역시 문제점이 없었다. 그러다 문득 계측기 업체가 자기들 계측기를 사용하기 위해 제공한 소스코드를 그대로 복붙에서 사용한 부분이 있었는데 처음에는 계측기 업체에서 제공한 코드라서 전혀 의심을 하지 않았기에 혹시나 하고 그 코드를 AI에게 물어 보니 Variant 변수를 설정해서 사용하고는 변수에 대한 메모리 해제를 하지 않아 메모리 오버플로우가 발생한 사실을 찾아 내었다. AI 가 아니었으면 원인 찾는데 꽤 많은 시간을 낭비할 뻔 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;그런데 이렇게 조금씩 인공지능에 의존하다 보니 왠지 이제는 코드짜는데 머리쓰는것이 너무 너무 귀찮게 생각된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;이러다가는 머리가 썩어서 기본적인 코드도 못짜게 되는게 아닌지 한편으로는 걱정도 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;계산기를 사용하고 부터는 기초적인 사칙연산도 귀찮고 어렵게 느껴지는 것처럼 이제 코딩도 너무 귀찮게 생각되고 말로 몇마디 하면 그냥 프로그램 뚝딱 만들어 줘 버리는 세상이 되면 나같은 개발자들은 다 없어질지도 모르겠다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;</description>
      <category>Developer's Story</category>
      <category>AI</category>
      <category>chat-gpt</category>
      <category>인공지능</category>
      <author>sihwankim</author>
      <guid isPermaLink="true">https://auto-control.tistory.com/85</guid>
      <comments>https://auto-control.tistory.com/85#entry85comment</comments>
      <pubDate>Thu, 27 Feb 2025 13:46:48 +0900</pubDate>
    </item>
  </channel>
</rss>