:: 진공에 대해 알려주마.

PC로 실내 온도나 읽어 보자! (MODBUS) 본문

OVER VENT

PC로 실내 온도나 읽어 보자! (MODBUS)

하이백 2020. 3. 17. 21:30

출장 전 시간이 좀 되는데 PC를 이용하여 실내 온도를 읽어보고자 한다. 시리얼 통신으로 포맷은 MODBUS-RTU를 지원하는 보드를 사용하였다.

사람이 실내의 온도를 읽기 위해서는 온도계를 필요로 한다. 온도계를 온도를 측정하고 쉽은 곳에 설치하고 눈으로 온도계의 눈금을 읽어 현재 온도를 확인할 수 있다.

온도계

 

하지만 PC를 이용하여 온도를 읽고자 할 때는 다음과 같은 몇 가지 장치가 필요하다. 온도 변화를 인식하고 이를 계산하여 디지털화 할 수 있는 장치가 필요하다.

  1. 온도를 전기적 신호를 변환할 수 있는 온도 센서 (Thermistor, thermocouple, RTD)
  2. 센서에서 변환된 신호를 Voltage 등으로 변환할 수 있는 모듈 (AD Converter)
  3. 보드에서 읽은 값을 PC가 읽을 수 있도록 하는 디지털화 하는 보드 (DAQ Board)

온도를 읽기 위해서는 온도를 아날로그 신호나 디지털 신호 변환할 수 있는 온도계가 필요한다. 이러한 기능을 하는 전자 부품이 Thermistor, thermocouple, RTD 등이 있다.

Thermistor, thermocouple, RTD의 차이점은 아래를 참고하시고...
https://www.ni.com/ko-kr/innovations/white-papers/06/overview-of-temperature-sensors.html

가장 흔히 구할 수 있는 Thermistor를 이용하여 실내 온도를 읽어 보고자 한다. 우리 업계에서는 TC(Thermocouple)를 주로 사용하고 좀 더 정확한 온도 측정을 위해서는 RTD를 주로 사용한다.  

PC에서 온도 측정을 위하여 Thermistor를 바로 읽을 수는 없으며 Thermistor에서 측정된 값을 PC가 인식하기 위해서는 Thermistor에서 측정된 값을 읽을 수 있는 특정 보드를 PC에 설치하거나 아니면 PC에서 쉽게 읽을 수 있도록 값을 변환해 주는 외부 변환 보드가 필요하다.

이것저것 찾아보다 선정한 것이 의 Thermistor값을 측정하여 시리얼 통신으로 PC와 온도 값을 주고받을 수 있는 보드가 있어 이를 사용하기로 했다. 시리얼 통신은  RS-485 ModBus RTU를 지원한다.

 

COMFILE사의 ML-NTC2

 

이 보드는 Thermistor 두 개를 연결할 수 있고 여기서 읽은 값을 RS-485 통신 방식으로 외부로 전달할 수 있다. 이를 이용하여 PC에서 RS-485 통신으로 Thermistor의 값을 읽어 화면에 표시하면 된다.

내 노트북 PC에는 시리얼 포트가 없어 USB-RS485 변환 컨버터를 사용하였다.

 

 

RS-485 통신에서 반드시 필요한 장치의 어드레스 설정 방법과 통신 규격은 다음과 같다. 장치의 어드레스와 통신 규격은 장치와 같이 제공된다. 

RS-232의 경우 장치 어드레스가 필요 없는 일대일 통신 방식이다. 하지만 RS-485 통신 방식은 여러 개의 장치를 연결하여 사용하는 멀티드롭 방식으로 반드시 장치마다 고유 어드레스를 가져야 한다. 

RS-485 통신 방식은 2 Wire와 4 Wire의 두 가지 구성 방식이 있으며 아래 링크를 참고하시라.
https://m.blog.naver.com/k_dynamic/220920194625

 

온도변화모듈의 어드레스 설정방법과 통신사양

 

온도 변환 모듈은 아래와 같은 명령어가 하나이다. T1과 T2의 온도를 읽어오는 명령이고 MODBUS-RTU 형식이며 RTU(Remote Terminal Unit)는 터미널 혹은 HMI에서 장치(주로 PLC)의 값에 접근하여 bit/word 단위로 가져오게 된다. 산업 표준으로 자리하고 있어 거의 모든 PLC와 많은 장치가 이를 지원한다. 

MODBUS-RTU를 지원하는 HMI가 있다면 HMI에 장치 어드레스와 주소만 설정하면 이 장치에서 온도 값을 바로 가져올 수 있다. Coil과 registers로 불리는 bit값과 word 형태 규격의 값을 읽고 쓸 수 있다. 

MODBUS RTU 형식의 통신 명령 규격

 

그리고 한 가지 더 확인해야 할 것은 Error 관련 항목이다. 온도를 읽기 위해 명령을 송신하면 수신하여 축출된 값이 아래와 같으면 장치 에러를 의미하며 이는 온도 값이 아니어서 별도 처리가 필요하다.

회신된 값은 온도에 해당하는 부분이 위와 같으면 에러 처리 해야 한다.

 

이제 장치를 연결하고 온도를 읽어보자. 

MODBUS-RTU는 ASCII코드가 아닌 Hex code를 이용하여 패킷을 구성하므로 Hex code를 적용하여 명령어를 송신할 수 있는 테스트 킷이 필요하다. 테스트 킷은 comfile사의 CFTerm v1.42를 사용하였다.

우선 장치가 지원하는 통신 프로토콜을 설정하고 Open(연결)한 다음 아래와 같이 진행한다.
Protocol에 MODBUS RTU를 선택하고
Function에는 Word Read [03]을 선택하고
Start Address(Hex)에는 01F4 (십진수 500을)
Slave Address에는 1을 (ID 스위치를 이용하여 온도 변환 모듈에 ID 1로 설정)
Length에 parameter의 의미와 비슷하며 2 채널 의미로 2를 입력하고 Send를 클릭한다.

Thermistor1=0AF9=2809=28.09도

회신된 Rx의 값은 0A F9로 이를 그대로 10진수로 환산하면 2809이다. 이를 설명서에 나와있는 것처럼 고정 소수점 자리를 추가하면 28.09도이다.

온도 변화를 확인하기 위하여 thermistor를 손으로 만지면 0C E8이 회신되며 이는 십진수로 변환하면 3304이며 이는 33.04도를 나타낸다.

아래의 이미지는 위의 MODBUS를 지원하는 기능을 사용하지 않고 modbus에서 정의한 내용을 집적 장치에 전송하여 얻은 결과값이다. 전송된 protocol만 다를 뿐 같은 내용을 의미한다. (CRC 값도 손으로 계산하여 집적 입력해야 한다.)

MODBUS가 아닌 Hex code로 집적 전송해도 같은 결과를 얻을수 있다.

 

툴을 이용한 통신 테스트는 잘 진행이 되었다. 값도 잘 올라온다. 이러한 pre-check 과정을 거치는 이유는 내가 만들 통신 프로그램의 오류를 미리 검사하여 내 프로그램의 오류를 제외하면 문제가 없다는 것을 확인하기 위해서다. 결국 내가 잘못해서 통신이 안되는 것이지 다른 이유로 통신이 안되는 것은 없다는 뜻이다.

이러한 과정을 생략하면 통신이 안되는 경우 케이블, NCT보드, 서미스터 아니면 USB컨버터 모두를 의심해야 한다. 

위의 테스트를 중심으로 프로그램하여 화면에 온도를 표시해 보겠다. 절차를 프로그램으로 구성하면...

  • 포트를 오픈하고
  • 통신 규격을 설정하고
  • 0x01 0x03 0x01 0xF4 0x00 0x02 0x84 0x05 를 문자열로 만들어 전송
  • 회신된 내용에서 4,5번 바이트를 잘라낸다.
  • 화면에 표기 다음과 같이 표시한다. 4번 바이트 + '.' + 5번 바이트

이를 폼으로 구성하고 위의 순서에 따라 코딩하면 현재 온도를 PC에서 표시하여 볼 수 있다.

 

화면은 이정도로 만들고.

프로그램은 

using System;
using System.Windows.Forms;
using System.IO.Ports;
using System.Text;

namespace Thermistor
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btn_Connect_Click(object sender, EventArgs e)
        {
            if (T485Port.IsOpen == false)
            {
                // 시리얼 포트 설정
                T485Port.PortName = "COM5";
                T485Port.BaudRate = 57600;
                T485Port.DataBits = 8;
                T485Port.Parity = Parity.None;
                T485Port.StopBits = StopBits.One;

                // 시리얼 포트 오픈
                T485Port.Open();

                // 온도를 읽어오기 위한 명령 송신용 타이머
                tmrPoll.Enabled = true;
                tmrPoll.Interval = 100;
                tmrPoll.Start();
            }
            else
            {
                // 열려있음.
            }
        }

        // 해제(종료) 버튼 처리
        private void btn_DisConnect_Click(object sender, EventArgs e)
        {
            tmrPoll.Stop();
            T485Port.Close();
        }


        // 변환된 값을 라벨에 붙이기 위한 전역 변수
        string gTemp = "";

        // 온도를 읽기 위한 명령
        byte[] Hex = new byte[8] { 0x01, 0x03, 0x01, 0xF4, 0x00, 0x02, 0x84, 0x05 };
        //

        private void tmrPoll_Tick(object sender, EventArgs e)
        {
            if (T485Port.IsOpen)
            {
                T485Port.Write(Hex, 0, Hex.Length);
            }
            // 
            lb_Temperature.Text = gTemp;
        }

        // 시리얼 포트에 문자가 들어오면 이를 처리한다.
        private void T485Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] rcvVal = new byte[255];

            if (T485Port.IsOpen)
            {
                T485Port.Read(rcvVal, 0, 255);

                // 8자 이하는 버린다.
                if (rcvVal.Length < 8) return;

                string hexVal = string.Format("{0:X2}{1:X2}", rcvVal[3], rcvVal[4]);
                int intVal = Convert.ToInt32(hexVal, 16);

                string strDecVal = string.Format("{0,6}", intVal.ToString());
                gTemp = strDecVal.Substring(0, 4) + "." + strDecVal.Substring(4, 2);
            }
        }

    }
}

 

타이머 속도를 줄여 업데이트 속도를 높이니 원치 않는 값을 가져온다. 이는 회신된 내용을 확인하고 회신된 내용을 parsing 하는 부분에서 걸러내거나 회신된 내용중 CRC를 계산하여 오류가 확인되면 해당 회신 내용을 버리고 다시 받아서 사용하면 된다. 이렇게 까지 처리하면 완벽한 온도계가 될 것이다. 

 


 

추가로 TCP/IP를 이용한 모드버스를 테스트 하고자 한다면 아래의 주소에서 모드버스 TCP 테스트 프로그램을 다운 받은후 아래의 내용과 같이 입력후 통신을 테스트 하면 된다.

https://blog.naver.com/PostView.nhn?blogId=kisan_system&logNo=30186516478&parentCategoryNo=&categoryNo=46&viewDate=&isShowPopularPosts=true&from=search  

통신 케이블을 연결하고 프로그램을 실행시키서 다음의 값들을 확인하고 해당 항목에 설정하면 된다.

연결 / 설정후연결
    IP Address 설정

설정 / Read Definition...
    Slave ID : PLC에 접근하기 위한 장치 ID를 뜻하며 PLC에 설정되어 있음.
    Function : 04 Read Input Registers(3X)로 설정 (bit를 읽으려고 하면 02)
    Address  : 읽을 시작 주소
    Quantity : 시작 주소에서 몇개 읽을지.
    Scan Rate : 얼마마다 한번씩 읽을지 설정.

 

'OVER VENT' 카테고리의 다른 글

커넥터, 전선 그리고 압착기  (2) 2020.12.28
중국의 아침  (0) 2020.09.05
생산설비 이설(移設)  (0) 2020.07.05
AFTER MARKET  (0) 2020.06.24
중국으로  (0) 2020.06.21
Comments