본문 바로가기

프로그래밍/C

[C언어]리눅스 Modbus통신 RS485 Read input registers

반응형

요즘 자동화 설비를 안쓰고 맨손으로 무언가를 제작하는 회사는 찾기 힘들죠?

이런 자동화 설비들에는 거의 'ModBus통신'으로 통신이 가능하게 설계되어 있습니다.

그럼 이번시간에는, 리눅스 운영체제에서 Modbus로 값을 읽어오는

'Read input registers'에 대한 코드를 살펴보겠습니다.

 

리눅스 운영체제로 Modbus통신하는것이

한글자료가 하~나도 없어서 자료를 찾는것이 어려웠네요 ㅜ

암튼 시작해보죠!

~~~

 

 

~

코드

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/types.h>

#include <termios.h>

#include <fcntl.h>

#include <errno.h>

#include <time.h>

#include <modbus.h>

 

enum {TCP, RTU};

 

int main(void)

{

  int a;

  uint16_t test;

  modbus_t *mb;

 

  mb = modbus_new_rtu("/dev/ttyUSB0",38400,'N',8,1); //PortNumber

// RS485통신할 통신포트와 통신설정 정확히 아셔야합니다!

 

  if (mb == NULL)

  {

fprintf(stderr, "Unable to create the libmodbus context for RTU: %s\n", modbus_strerror(errno));

return -1;

  }

 

  if(modbus_set_slave(mb, 1) == -1) // Station ID

  {

    fprintf(stderr, "Unable to set the slave ID in context for RTU: %s\n", modbus_strerror(errno));

return -1;

  }

  printf("\n setted slave!!!!\n");

  modbus_set_debug(mb,TRUE);

 

  if (modbus_connect(mb) == -1)

  {

    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));

    modbus_free(mb);

    return -1;

  } 

 

  struct timeval response;

  response.tv_sec = 0;

  response.tv_usec = 1000;

  modbus_set_response_timeout(mb, 0, 1000);

// 이 함수가 예제에 따라 인자값이 다르니 주의해서 사용하셔아할 것 같습니다.

 

a = modbus_read_input_registers(mb,0x1101,1,&test);



  printf("\n Value of a is: %d\n",a);

  printf("\n Value of a is: %d\n",test);

scanf("%d",&test);

  

  if (a==-1)

       fprintf(stderr, "Custom error: %s\n", modbus_strerror(errno));

}

 

기타 함수에 대한 자세한 설명은

 

modbus_read_input_registers(3) — libmodbus-dev — Debian testing — Debian Manpages

modbus_read_input_registers - read many input registers SYNOPSIS¶ int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest); DESCRIPTION¶ The modbus_read_input_registers() function shall read the content of the nb input registers t

manpages.debian.org

이 사이트를 참조하시면 됩니다.

 

~

 

 

 

~

실행결과

 

윈도우와 라즈베리파이(리눅스)를 연결해서 485 Modbus통신을 해 본 결과,

리눅스에서 윈도우로 제가 원하는 Modbus 통신 Frame이 정확히 전달된 것을 확인할 수 있습니다.

 

+설정

윈도우와 라즈베리파이에선 'Systembase사의 Usb to 485 Converter'를 사용했고

통신설정은 Baudrate 38400, 1Stop bits, No parrity, 8data bits

라즈베리파이(리눅스)에서는 g++를 이용해 코드를 컴파일하였고

윈도우에선 COM ANALYZER를 통해 Modbus Frame을 수신하였습니다.

 

~

 

 

 

~

모드버스 통신을 잘 모르시는 분들은

이 프로그램을 이해하기 힘드니까 저의 구글검색법을 이용해

'filetype:PDF 모드버스'같은 식으로 예제를 공부해보시고!

이 프로그램을 보시면 됩니다.

 

그리고 추가로 모르는게 있으면

시간날 때 최대한 답변드릴테니 댓글 달아주세요!

 

반응형