[아두이노] 1:N 아두이노 간 I2C 통신
[아두이노] 1:N 아두이노 간 I2C 통신
- 온라인 가상시뮬레이터 : https://www.tinkercad.com
- 사전학습 : [아두이노] 아두이노 간 I2C 통신
- 공개회로도 : https://www.tinkercad.com/things/dIcybQ2vHWd
지난시간에 아두이노간 I2C 통신 실험을을 하기 위해서 공유선을 A4(SDA), A5(SCL)핀에 연결하여 2대의 아두이노 간 통신을 했었습니다. 오늘은 마스터 아두이노와 2대의 슬레이브 아두이노 간의 통신을 연장해서 실험을 해보겠습니다. 지난 시간의 실험 내용에서 아두이노가 한 대 더 추가되었을 뿐 변동 사항은 거의 없습니다. 오늘 실험은 마스터 아두이노에 슬레이브 아두이노 2대를 연결하여 실험하지만 더 많은 아두이노로 통신 하시고 싶다면 2대 이상 연결하여 실험을 하셔도 됩니다. 슬레이브 아두이노의 갯수는 여러분들이 정해서 실험하시면 됩니다.
이제 1:N 아두이노들 간의 I2C 통신 실험을 해보도록 하죠.
1. 1:N 아두이노 I2C 통신 회로도
준비물 : 아두이노우노 3개
내용 : 아두이노우노의 A4(SDA), A5(SCL)핀을 서로 공유한다.
회로도의 선 연결은 지난 시간에 아두이노 간의 I2C 통신 회로도에서 아두이노 한대가 더 추가 된 회로도 입니다.
2. 코딩
- 참고 출처 : https://www.arduino.cc/en/Reference/Wire
- 사전학습 : [아두이노] 아두이노 간 I2C 통신
사전 학습에서 사용된 코딩을 약간만 수정하시면 됩니다.
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로 다시 이야기를 하게 되었습니다.
'IOT > 아두이노' 카테고리의 다른 글
[아두이노] 아두이노 간 I2C 통신 응용 (0) | 2019.08.26 |
---|---|
[아두이노] n:m 아두이노 간 I2C 통신 (0) | 2019.08.23 |
[아두이노] 아두이노 간 I2C 통신 (0) | 2019.08.21 |
[아두이노] 시리얼 통신으로 다수 명령 처리 방법 (0) | 2019.08.19 |
[아두이노] 아두이노 피아노 만들기 (0) | 2019.08.16 |