[아두이노] 1:N 아두이노 간 I2C 통신

IOT/아두이노|2019. 8. 22. 09:00

[아두이노] 1:N 아두이노 간 I2C 통신



지난시간에 아두이노간 I2C 통신 실험을을 하기 위해서 공유선을 A4(SDA), A5(SCL)핀에 연결하여 2대의 아두이노 간 통신을 했었습니다. 오늘은 마스터 아두이노와 2대의 슬레이브 아두이노 간의 통신을 연장해서 실험을 해보겠습니다. 지난 시간의 실험 내용에서 아두이노가 한 대 더 추가되었을 뿐 변동 사항은 거의 없습니다. 오늘 실험은 마스터 아두이노에 슬레이브 아두이노 2대를 연결하여 실험하지만 더 많은 아두이노로 통신 하시고 싶다면 2대 이상 연결하여 실험을 하셔도 됩니다. 슬레이브 아두이노의 갯수는 여러분들이 정해서 실험하시면 됩니다.

이제 1:N 아두이노들 간의 I2C 통신 실험을 해보도록 하죠.

1. 1:N 아두이노 I2C 통신 회로도


준비물 : 아두이노우노 3개
내용 : 아두이노우노의 A4(SDA), A5(SCL)핀을 서로 공유한다.



회로도의 선 연결은 지난 시간에 아두이노 간의 I2C 통신 회로도에서 아두이노 한대가 더 추가 된 회로도 입니다.

2. 코딩



사전 학습에서 사용된 코딩을 약간만 수정하시면 됩니다.

1) 마스터 아두이노 코딩


설계 :

  • 각 슬레이브 아두이노에 데이터 전송
  • 각 슬레이브 아두이노에 데이터 요청과 수신

동작은 위 2가지 형태로 실험이 이루어 집니다. 아래 그림처럼 그림A와 그림B 동작을 마스터 아두이노는 각 슬레이브 아두이노 간의 순차적으로 동작하게 됩니다.


[지난소스]

  //데이터 전송
  Wire.beginTransmission(1);                 
  Wire.write("good ");       
  Wire.write(x);             
  Wire.endTransmission();    
     
  delay(500);
    
  //데이터 요청 & 수신
  Wire.requestFrom(1, 4); //슬레이브(1)에 4byte 요청
  while (Wire.available()) {
    char c = Wire.read(); 
    Serial.print(c);        
  }  

지난시간에 슬레이브 아두이노에 특정 데이터를 전송한 뒤에 다시 데이터를 요청 했었습니다. 1대가 아니고 2대의 슬레이브 아두이노에 데이터를 전송하고 데이터를 요청하도록 수정 한다면 어떻게 해야 할까요.

동작은 설계에서 딱 두개의 동작만을 수행 합니다. 데이터를 전송하고 데이터를 요청한다. 이 두가지 동작을 2대의 슬레이브 아두이노와 통신을 해야 한다면 지난 소스을 적용한다면 2번 반복 수행해야 겠죠. 그러면, 위 코딩을 복사해서 길게 두번 코딩해야 할까요. 그럴 필요는 없습니다. for문으로 두번만 위 코딩을 반복시키면 됩니다.

각 슬레이브 주소를 1, 2번으로 지정해 주고 아래와 같이 코딩하면 됩니다.

  for(int i=1;i<3;i++){
    Wire.beginTransmission(i);                
    Wire.write("test ");       
    Wire.write(i);             
    Wire.endTransmission();    
     
    delay(500);
    Wire.requestFrom(i, 4);   
    while (Wire.available()) {
        char c = Wire.read(); 
        Serial.print(c);        
    }
  }   

간단하죠. 여기서, 아두이노가 N대를 연결한다면 for문의 i값의 N 횟수 만큼 반복되도록 숫자만 변경해주면 여러대의 슬레이브 아두이노와 통신을 할 수 있게 됩니다.

2) 슬레이브 아두이노 코딩


설계 :

  • 데이터 수신 처리
  • 데이터 요청 응답

지난 시간의 코딩과 동일합니다. 식별 번호만 바꿨네요. "ok1"으로 해당 슬레이브 아두이노의 요청 메시지만 수정했네요.

  Wire.onRequest(requestEvent); //요청시 requestEvent함수 호출
  Wire.onReceive(receiveEvent); //데이터 전송 받을 때 receiveEvent함수 호출
void receiveEvent(int howMany) { //전송 데이터 호출시 명령
  while (Wire.available()>1) { 
    char ch = Wire.read(); 
    Serial.print(ch);         
  }
  int x = Wire.read();    
  Serial.println(x);      
}
void requestEvent() { //마스터 요청 시 수행 함수
  Wire.write("ok1\n");   
}

여기서, 두 대의 슬레이브 아두이노로 실험하니깐 요청이 들어오면 "ok1", "ok2"로 메시지가 출력되게 코딩하면 됩니다.

종합해보면,

[마스터 아두이노]

#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600); 
}

void loop() {  
  for(int i=1;i<3;i++){
    Wire.beginTransmission(i);                
    Wire.write("test ");       
    Wire.write(i);             
    Wire.endTransmission();    
     
    delay(500);
    Wire.requestFrom(i, 4);   
    while (Wire.available()) {
        char c = Wire.read(); 
        Serial.print(c);        
    }
  }   
}

[슬레이브 아두이노 1]

#include <Wire.h>

void setup() {
  Wire.begin(1); //슬레이브 주소                
  Wire.onRequest(requestEvent); //마스터 요청시 requestEvent함수 호출
  Wire.onReceive(receiveEvent); //마스터 데이터 전송시 receiveEvent함수 호출

  Serial.begin(9600);           
}

void loop() {
  delay(500);
}

void receiveEvent(int howMany) { //전송 데이터 호출시 명령
  while (Wire.available()>1) { 
    char ch = Wire.read(); 
    Serial.print(ch);         
  }
  int x = Wire.read();    
  Serial.println(x);      
}
void requestEvent() { //마스터 요청 시 수행 함수
  Wire.write("ok1\n"); 
  
}

[슬레이브 아두이노 2]

#include <Wire.h>

void setup() {
  Wire.begin(2);                
  Wire.onRequest(requestEvent); //마스터 요청시 requestEvent함수 호출
  Wire.onReceive(receiveEvent); //마스터 데이터 전송시 receiveEvent함수 호출
  Serial.begin(9600); 
}

void loop() {
  delay(500);
}

void receiveEvent(int howMany) { //전송 데이터 호출시 명령
  while (Wire.available()>1) { 
    char ch = Wire.read(); 
    Serial.print(ch);         
  }
  int x = Wire.read();    
  Serial.println(x);      
}
void requestEvent() { //마스터 요청 시 수행 함수
  Wire.write("ok2\n");   
}

3. 결과


위 코딩으로 1:N 아두이노 간의 I2C 통신을 할 수 있게 되었습니다. 가상시뮬레이터에서 결과가 어떻게 나오는지 영상으로 살펴보세요.


마무리


오늘은 1:1 I2C 통신하는 방식에서 1:N I2C 통신을 실험 했습니다. 오늘 내용은 지난 시간에 했던 내용을 for문 하나가 추가 되었을 뿐 따로 추가된 부분은 없습니다. 여러대를 연결하면 각 슬레이브 아두이노로 데이터를 보내고 각 슬레이브 아두이노에 데이터를 요청하면 거기에 맞게 각 슬레이브 아두이노는 데이터 수신과 데이터 요청에 대한 응답 처리 코딩만 하면 됩니다.

오늘은 그냥 복습차원으로 반복 학습 post입니다. 1:1 통신을 할 수 있으면 1:N 통신을 잘 생각하면 쉽게 떠올릴 수 있는데 혹시 1:N이 잘 연상이 안되는 분들이 있을 것 같아서 지난시간에 마무리 글로 1:N 통신으로 연장해서 상상을 해보시라고 했는데 못하시는 분들을 위해 이렇게 post로 다시 이야기를 하게 되었습니다.


댓글()