라즈베리파이, 아두이노

[아두이노] 두개의 아두이노 사이의 RS485 통신

포도알77 2019. 3. 23. 18:35

 아두이노 우노를 이용해서 RS485 통신하는 방법을 설명하고자 한다.

RS485의 물리계층(1계층)이 어떻게 동작하는지는 정확한 프로토콜을 찾아보지 않았으나, 반이중통신으로 아두이노에서 Serial을 이용하여 통신을 할 수 있다.



 RS485는 P, N(A, B)의 두 개의 링크로 기기간 연결되며, 64개의 장치까지 한번에 연결할 수 있다고 알려져있다. 또한 4000피트까지 연결 가능하다고 하니, 원격지의 장치에서 데이터를 뽑아오는데 유용하다.



 대충 검색을 해보니, TTL to RS485 모듈을 이용해서 통신을 한다. 나는 천원 내외인 MAX485가 장착된 컨버터를 이용했다. 더 검색을 해봐야겠지만 직접 A, B 링크를 읽거나 쓰는 것이 가능한 것 같아보이는데, 정확한 내용은 직접 확인하기 바람. (RS485의 A,B 링크 전압을 TTL로 낮추는 컨버터가 있어야 직접 읽고 쓰기가 가능함)



1) 아두이노 우노 기준, RS485 커넥터 연결

 (1) 아두이노의 4,5번 핀을 MAX485 컨버터의 R0 / DI에 각각 연결

 (2) 아두이노의 2번 핀 DE와 RE는 쇼트 후 연결

 (3) 두 개의 MAX485 컨버터의 A, B를 연결 (A-A / B-B로 연결한다. RX/TX 연결하듯 교차하면 안된다.)

 (4) 하나의 아두이노를 마스터 역할 (데이터 전송)

 (5) 또 다른 하나의 아두이노를 슬레이브 역할 (데이터 수신) 으로 수행



2) 소스코드

 [마스터 코드]

//마스터 코드
#include 

// 전송 ENABLE 핀 2
int EN = 2;
int val;

// 시리얼 핀 4,5 (RX-RO/TX-DI)
SoftwareSerial rx485(4,5);

void setup()
{
  // BuadRate를 9600으로 맞춤
  Serial.begin(9600);
  rx485.begin(9600);
  // 전송 ENABLE 핀 출력 설정
  pinMode(EN, OUTPUT);
}
void loop()
{
  // EN핀 HIGH 설정 후 데이터 전송
  digitalWrite(EN, HIGH);
  rx485.print("A");
  delay(3000);
}


 [슬레이브 코드]

// 슬레이브 코드
#include 

// 전송 ENABLE 핀 2
// LED 핀13
int LED = 13;
int EN = 2;
int val;

// 시리얼 핀 4,5 (RX-RO/TX-DI)
SoftwareSerial rx485(4,5);

void setup(){
  // BaudRate를 9600으로 맞춤
  Serial.begin(9600);
  rx485.begin(9600);
  // LED 및 전송 ENABLE 핀 출력 설정
  pinMode(LED, OUTPUT);
  pinMode(EN, OUTPUT);
}
void loop()
{
  // rx485에서 읽을 값의 개수가 1개 이상이라면
  // 루프 주기에 따라서 3개를 보내었을 때 2, 1개씩 읽어지는 경우 발생
  // 따라서 readString으로 readStringUntil으로 처리하거나 Refine 해야함
  if(rx485.available()>=1){
    digitalWrite(EN, LOW);
    val = rx485.read();
    // 읽은 데이터가 A이면 LED 블링크
    if(val == 'A'){
      digitalWrite(LED, HIGH);
      delay(100);
      digitalWrite(LED, LOW);
    }
  }
}


3) 가장 눈에 띄는 것은 DE/RE를 디지털 핀에 연결하여, 쓸 때는 High 읽을 때는 LOW로 입력한다. 

 데이터를 읽을 때는 Refinement를 하거나, 아니면 readStringUntil같은 함수로 처리하자.




페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사