Embedded/RaspberryPI

Raspberry Pi CM4에 ModbusTCP Server 실행해 보기 - 3편(ModbusTCP server 수정된 함수사용)

변화의 물결1 2024. 11. 26. 10:35

 

 

안녕하세요.

 

 이전 글에서 deprecated 된 get_words() 함수 관한 부분을 완료하지 못하고 마무리했습니다.

이 부분을 다시 확인하고 정리해보려고 합니다. 기본 자료형과 구조는 동일합니다.

 


 

1. DataBank Class 최신 함수

 

 최신 버전에서는 DataBank를 직접 호출하는 대신, ModbusServer 객체의 data_bank 속성을 통해 접근합니다

 

1) DataBank의 메모리 구조

 

DataBank는 Modbus 표준 메모리 구조를 관리하며, 아래 4가지 메모리 타입을 제공합니다:

 

Coils (1-bit): 읽기/쓰기 가능한 디지털 값

Discrete Inputs (1-bit): 읽기 전용 디지털 값

Holding Registers (16-bit): 읽기/쓰기 가능한 16비트 값

Input Registers (16-bit): 읽기 전용 16비트 값

 

2) 메모리 관리 방식

 

 (1) 자동 메모리 생성

 

  데이터가 처음 설정될 때 메모리 공간이 자동으로 할당됩니다.

  주소 영역은 동적으로 확장되며, 값을 설정하지 않은 주소는 기본값(일반적으로 0)으로 초기화됩니다.

 

 (2) 수동 메모리 초기화

 

  사용자가 필요한 메모리 영역을 사전에 초기화하거나 값들을 설정할 수 있습니다.

 

3) DataBank 사용

 

 ModbusServer 객체의 data_bank를 사용해 데이터를 설정하거나 읽어오는 방식으로 관리합니다.

 

(1) 데이터 설정

  

# 서버 인스턴스 생성
from pyModbusTCP.server import ModbusServer

server = ModbusServer("localhost", 1502, no_block=True)

# Holding Registers 주소 0번에 값 1234 설정
server.data_bank.set_holding_registers(0, [1234])

# Coils 주소 0번~7번에 값 설정
server.data_bank.set_coils(0, [True, False, True, False, True, True, False, False])

 

 (2) 데이터 읽기

  

# Holding Registers 주소 0~5번 값 읽기
data = server.data_bank.get_holding_registers(0, 6)
print(data)  # 출력: [1234, 0, 0, 0, 0, 0]

# Coils 주소 0~7번 값 읽기
coils = server.data_bank.get_coils(0, 8)
print(coils)  # 출력: [True, False, True, False, True, True, False, False]

 

 

2. ModbusTCP 함수 수정된 코드

 

서버를 실행해서 1번 메모리 주소에 랜덤데이터를 저장하고 확인하는 소스코드입니다.

  

#!/bin/python

from pyModbusTCP.server import ModbusServer
from time import sleep
from random import uniform

# Create an instance of ModbusServer
server = ModbusServer("192.168.0.59", 1502, no_block=True)

try:
    print("Start server...")
    server.start()
    print("Server is online")
    state = [0]
    while True:
        # Set random value to Holding Register address 0
        server.data_bank.set_holding_registers(1, [int(uniform(0, 100))])
        print(server.data_bank.get_holding_registers(1))

        # Get the value from Holding Register address 2
        current_value = server.data_bank.get_holding_registers(2)

        # Check if value at Register 1 has changed
        if state != current_value:
            state = current_value
            print(f"Value of Register 2 has changed to {state[0]}")
        sleep(0.5)

except Exception as e:
    print(f"Error occurred: {e}")
    print("Shutdown server ...")
    server.stop()
    print("Server is offline")

 

 

3. 작동확인

 

Client는 기산 시스템에서 배포하는 KiMons 프로그램으로 확인했습니다.

라즈베리파이에서 실행한 ModbusTCP 서버주소를 설정합니다. 접속은 라즈베리파이에서 modbusTCP 서버를 실행 후 접속합니다.

 

 

 

ModbusTCP 라이브러리를 설치한 가상환경을 활성화한 후 python 파일을 실행합니다.

(내용을 확인하려면 이전 글을 확인하시면 됩니다.)

 

$ source ~/virtualEnv/bin/activate
$ python modbustcp.py

 

 

 ModbusTCP Client 프로그램으로 접속한 후 Function Codes를 03(Read Holding Registers)으로 선택한 후 주기적으로 읽어 오게 합니다. 그러면 서버 측(라즈베리파이)에서 1번 주소에 랜덤으로 변경된 값을 저장하고 클라이언트 프로그램에서 1번 주소값을 읽어오는 것을 확인할 수 있습니다.

 

 라즈베리파이에서는 0.5초로 변화하고 있고, client 프로그램에서는 1초당 한 번씩 읽어오고 있어 다른 것처럼 보일 수 있습니다. 서로 간 주기를 맞춰서 읽어오는 것을 조정하면 됩니다.

 

 

 

감사합니다.

 

 

반응형