학습목표    1

학습주제    1

예습내용    1

실습방법    1

        1

중요함수    1

탱크 수위 측정

학습목표

액체가 저장된 탱크의 수위를 측정한다.

학습주제

1.      수위 측정기는 씨디아이테크㈜(http://www.cdikorea.com) 판매되는 모델번호 CDT-100R 사용하였다.

2.      전압의 측정은 NI(http://www.ni.com/korea) “NI USB-6008 사용 하였다.

3.      기기에서는 4~20mA 전류가 출력됨으로 500오옴 저장을 연결하여 2~10V 출력이 나오도록 하였다.

4.      프로그램에서 0.5 마다 타이머를 동작시켜서 전압을 축정하고 이를 프로그램의 슬라이드에 연결하여 프로그램한다.

5.      하위레벨과 상위레벨에서 출력포트 P0.0 P0.1 출력이 나가도록 프로그램한다.

6.      프로그램은 C:\Documents and Settings\All Users\Documents\National Instruments\NI-DAQ\Examples\MStudioVC2005\Analog In\Measure Voltage\AcqOneVoltageSample 예제프로그램을 기본으로 하여 응용한다.

 

 

다음과 회로를 연결한다.

이 때 “USB-6008”에는 DC24VAC220V 단자가 연결되면 PC가 회손 됨으로 각별히 조심해야 한다.

예습내용

수위 측정기는 4~20mA 전류가 출력되고, “NI USB-6008” 10V 까지 입력 전압이 허용 됨으로 아래와 같이 계산하여 연결 저항을 결정한다.  최대 전압을 10V, 전류를 20mA 하면 10V/0.02A=500오옴

 

실습방법

   

 

아래와 같이 “NI MFC Application”으로 프로젝트를 만든다. 그리고 나머지는 기본값으로 선택한다.

 

위에 속성 페이지 선택하여 아래와 같이 탱크 모양의 슬라이드로 바꾼다.

마우스 오른쪽버튼을 눌러 아래와 같이 변수 추가선택 한다.

변수 이름 “m_Tank1” 한다.

마우스로 다이어로그박스 선택한 후에 메시지에서 “WM_TIMER” 함수를 만든다.

LevelDlg.h 헤더 파일에 Task 정의 합니다.

 

// LevelDlg.h : 헤더파일

//

 

#pragma once

#include "nislide.h"

 

 

// CLevelDlg 대화상자

class CLevelDlg : public CDialog

{

// 생성입니다.

public:

        CNiDAQmxTask TaskIn01;

        CLevelDlg(CWnd* pParent = NULL); // 표준생성자입니다.

 

// 대화상자데이터입니다.

        enum { IDD = IDD_LEVEL_DIALOG };

 

        protected:

        virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.

//==================이하 생략 ===================

 

OnInitDialog() 함수 안에 Task를 아나로그 입력으로 설정 하고 타이머 동작 시간을 0.2초로 설정 합니다.

 

BOOL CLevelDlg::OnInitDialog()

{

        CDialog::OnInitDialog();

 

        // 시스템메뉴에"정보..." 메뉴항목을추가합니다.

 

        // IDM_ABOUTBOX는시스템명령범위에있어야합니다.

        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

        ASSERT(IDM_ABOUTBOX < 0xF000);

 

        CMenu* pSysMenu = GetSystemMenu(FALSE);

        if (pSysMenu != NULL)

        {

                CString strAboutMenu;

                strAboutMenu.LoadString(IDS_ABOUTBOX);

                if (!strAboutMenu.IsEmpty())

                {

                        pSysMenu->AppendMenu(MF_SEPARATOR);

                        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

                }

        }

 

        // 이대화상자의아이콘을설정합니다. 응용프로그램의주창이대화상자가아닐경우에는

        //  프레임워크가이작업을자동으로수행합니다.

        SetIcon(m_hIcon, TRUE);                  // 큰아이콘을설정합니다.

        SetIcon(m_hIcon, FALSE);         // 작은아이콘을설정합니다.

 

        // TODO: 여기에추가초기화작업을추가합니다.

        double minimum=-10;

        double maximum=10;

 

        TaskIn01.AIChannels.CreateVoltageChannel("Dev1/ai0",_T(""),

            static_cast<DAQmxAITerminalConfiguration>(-1),

            minimum, maximum, DAQmxAIVoltageUnitsVolts);

       SetTimer(1,200,NULL);

 

        return TRUE;  // 포커스를컨트롤에설정하지않으면TRUE를반환합니다.

}

 

타이머 함수에서 아나로그 입력포트의 값을 읽어오고 탱크레벨로 출력한다.

 

void CLevelDlg::OnTimer(UINT_PTR nIDEvent)

{

        // TODO: 여기에메시지처리기코드를추가및/또는기본값을호출합니다.

        CNiString data;

       double meanValue;

 

        //데이터를측정한다.

        CNiDAQmxAnalogSingleChannelReader reader(myTask1.Stream);

 

        //측정값을탱크레벨로출력한다.

        data<<reader.ReadSingleSample();

       data >> meanValue;

       TaskIn01.Value = meanValue;

 

        CDialog::OnTimer(nIDEvent);

}

 

프로그램을 동작하면 레벨이 표시되는 것을 있다.

지금부터 탱크의 상위,하위 레벨을 세팅하는 슬라이드와 Led를 추가하고 이에 따라 출력을 내보내도록 하겠습니다.

 

그림과 같이 슬라이드를 추가하고 변수를 추가 합니다.

변수 이름을 “m_Alarm1”로 합니다.

오른쪽 위 속성페이지를 선택한 후에 “Pointer”에서 “Add”버튼을 2번눌러 포인터 2개를 추가한 후에 “Min”, “Max”로 이름을 바꾸고 “Fill style”과 색상을 바꾼다.

그림과 같이 Led 2개를 만들고 위와 같이 변수추가를 선택하여 각각의 변수 이름을 m_bLedd1_1”, “m_bLedd1_2로 합니다.

LevelDlg.h 헤더 파일에 Task를 선언 합니다.

 

// LevelDlg.h : 헤더파일

//

 

#pragma once

#include "nislide.h"

#include "nibutton.h"

 

 

// CLevelDlg 대화상자

class CLevelDlg : public CDialog

{

// 생성입니다.

public:

        CNiDAQmxTask TaskIn01;       // 입력을위한Task

        CNiDAQmxTask TaskOut01;      // 출력을위한Task

        CLevelDlg(CWnd* pParent = NULL); // 표준생성자입니다.

 

// 대화상자데이터입니다.

        enum { IDD = IDD_LEVEL_DIALOG };

 

        protected:

        virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 지원입니다.

 

 

 

BOOL CLevelDlg::OnInitDialog()

{

        CDialog::OnInitDialog();

 

        // 시스템메뉴에"정보..." 메뉴항목을추가합니다.

 

        // IDM_ABOUTBOX는시스템명령범위에있어야합니다.

        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

        ASSERT(IDM_ABOUTBOX < 0xF000);

 

        CMenu* pSysMenu = GetSystemMenu(FALSE);

        if (pSysMenu != NULL)

        {

                CString strAboutMenu;

                strAboutMenu.LoadString(IDS_ABOUTBOX);

                if (!strAboutMenu.IsEmpty())

                {

                        pSysMenu->AppendMenu(MF_SEPARATOR);

                        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

                }

        }

 

        // 이대화상자의아이콘을설정합니다. 응용프로그램의주창이대화상자가아닐경우에는

        //  프레임워크가이작업을자동으로수행합니다.

        SetIcon(m_hIcon, TRUE);                  // 큰아이콘을설정합니다.

        SetIcon(m_hIcon, FALSE);         // 작은아이콘을설정합니다.

 

        // TODO: 여기에추가초기화작업을추가합니다.

        // 디지탈출력을위한초기화

        vector[0]=1;vector[1]=1;vector[2]=1;vector[3]=1;

       vector[4]=1;vector[5]=1;vector[6]=1;vector[7]=1;

      

       double minimum=-10;

        double maximum=10;

      

        TaskIn01.AIChannels.CreateVoltageChannel("Dev1/ai0",_T(""),

            static_cast<DAQmxAITerminalConfiguration>(-1),

            minimum, maximum, DAQmxAIVoltageUnitsVolts);

       TaskOut01.DOChannels.CreateChannel("Dev1/port0/line0:7", "",

                     DAQmxOneChannelForAllLines);

 

       SetTimer(1,200,NULL);

 

        return TRUE;  // 포커스를컨트롤에설정하지않으면TRUE를반환합니다.

}

 

OnTimer 함수에 수위를 측정하여 meanValue에 저장하고 led 출력과 디지털 포트 출력을 프로그램한다.

 

void CLevelDlg::OnTimer(UINT_PTR nIDEvent)

{

        // TODO: 여기에메시지처리기코드를추가및/또는기본값을호출합니다.

        CNiString data;

       double meanValue;

 

        //데이터를측정한다.

        CNiDAQmxAnalogSingleChannelReader reader(TaskIn01.Stream);

 

        //측정값을탱크레벨로출력한다.

        data<<reader.ReadSingleSample();

       data >> meanValue;

       m_Tank1.Value = meanValue;

       m_Alarm1.GetPointers().Item(1).Value = meanValue;

      

        // 탱크수위최대, 최소설정에따른출력을내보낸다.

        // 상위레벨보다높으면출력을멈춘다.

        if(meanValue >= m_Alarm1.GetPointers().Item(3).Value) {

              m_bLed1_1.Value = 1;

              vector[0]=1;

       }

       else

              m_bLed1_1.Value = 0;

 

        // 하위레벨보다낯으면출력을내보낸다.

        if(meanValue<=m_Alarm1.GetPointers().Item(2).Value) {

              m_bLed1_2.Value = 1;

              vector[0]=0;

       }

       else

              m_bLed1_2.Value = 0;

 

       CNiDAQmxDigitalSingleChannelWriter writer(TaskOut01.Stream);

       writer.WriteSingleSampleMultiLine(true, vector);

      

        CDialog::OnTimer(nIDEvent);

}

 

 

 

하위레벨보다 수위가 낮으면 Led에 불이 들어오고 디지털 포트 “P0.0”(평상시 5V출력)으로 출력을 0V를 내보내고 펌프가 동작하게 한다.

상위레벨보다 수위가 높으면 Led에 불이 들어오고 디지털 포트 “P0.0”(평상시 5V출력)으로 출력을 5V를 내보내고 펌프 동작을 멈추게 한다.

 

처음

   

 

중요함수