아두이노를 2대 혹은 그 이상 서로 연결해서 통신하는 방법을 모아봤습니다. 적외선, BT, WiFi 등 장치간 연결 방법이 아닌 시리얼(UART), I2C, SPI 통신을 이용해서 연결하는 방법입니다.
시리얼(UART) 통신으로 연결
시리얼 통신은 1:1 통신만 지원되므로 2대 연결시에만 사용 가능합니다. (단방향 통신일 때만 1:N 가능) 먼저 하드웨어 시리얼(아두이노 0, 1 번 핀)을 이용하는 방법입니다.
테스트를 위해 2 대의 아두이노를 사용합니다. 아두이노 2 는 주기적으로 문자 ‘1’ 과 ‘0’ 을 번갈아 전송합니다. 아두이노 1은 데이터를 받아 문자 ‘1’ 인 경우 내장한 LED 를 on 시키고 다른 문자인 경우 LED 를 off 시킵니다.
아두이노 두 대를 아래와 같이 TX – RX 크로스 해서 연결하면 됩니다. 각각의 아두이노는 USB를 통해 전원이 공급되는 상태여야 합니다.
연결 방법
- 아두이노1 ==> 아두이노 2
- 1번 핀(TX) ==> 0번 핀(RX)
- 0번 핀(RX) ==> 1번 핀(TX)
- GND ==> GND
스케치를 확인해 보겠습니다.
아두이노 1 (데이터 받아 LED 표시)
void setup(){ Serial.begin(115200); pinMode(13, OUTPUT); } void loop(){ if(Serial.available()){ char c = (char)Serial.read(); if(c == '1') { digitalWrite(13, HIGH); } else { digitalWrite(13, LOW); } } }
아두이노 SLAVE (데이터 보내는 부분)
void setup(){ Serial.begin(115200); } void loop(){ Serial.print("1"); // LED on delay(500); Serial.print("0"); // LED off delay(500); }
아두이노 1 이 내장한 LED가 0.5 초 간격으로 on/off 를 반복하면 정상입니다.
하드웨어 시리얼 대신 SoftwareSerial 을 사용해도 같은 결과를 얻을 수 있습니다.
I2C 통신으로 연결
I2C 통신은 Master/Slave 구분이 있습니다.
앞서와 같이 아두이노 2(Master)에서 데이터를 보내고 아두이노 1(Slave) 에서 데이터를 받아 내장 LED를 깜빡이도록 하겠습니다.
연결은 간단합니다. GND-GND 연결, A4(SDA, 데이터 라인) – A4 연결, A5(SCL, 클럭 라인) – A5 연결해주면 됩니다.
- 아두이노1 (Slave) ==> 아두이노 2 (Master)
- SDA ==> SDA
- SCL ==> SCL
- GND ==> GND
https://hardcopyworld.com/wp-content/uploads/2021/06/Master_Sender_bb-1.png
연결이 되면 코드는 아래와 같이 작성해서 올립니다.
아두이노 2 MASTER 코드 (데이터 보내는 부분)
#include <Wire.h> boolean isOn = false; void setup() { Wire.begin(); // join i2c bus (address optional for master) } void loop() { Wire.beginTransmission(8); // send to address #8 (0x08) if(isOn) Wire.write('1'); else Wire.write('0'); Wire.endTransmission(); isOn = !isOn; delay(500); }
아두이노 1 SLAVE (데이터 받는 부분)
#include <Wire.h> void setup() { Wire.begin(8); // use address #8 (0x08) Wire.onReceive(receiveData); } void loop() { delay(100); } void receiveData(int size) { while(1 < Wire.available()) { char c = Wire.read(); if(c == '1') digitalWrite(13, HIGH); else digitalWrite(13, LOW); } }
SPI 통신으로 연결
SPI 도 I2C 와 마찬가지로 Master/Slave 가 나뉩니다. 아두이노 1을 Slave(데이터 받는 용도), 아두이노 2를 Master(데이터 보내는 용도)로 설정해서 쓰겠습니다.
SPI 는 연결을 위해 4개의 디지털 핀을 사용합니다. D10(SS, Slave Select), D11(MOSI, Master Out Slave In), D12(MISO, Master In Slave Out), D13(SCLK, Serial Clock). 각각의 핀을 서로 연결해주면 됩니다.
그런데 SPI 경우 아두이노 내장 LED가 연결된 13번 핀과 겹칩니다. 앞서처럼 LED를 on/off 하기 위해 LED 하나를 디지털 5번 핀에 붙이도록 하겟습니다.
연결 방법
- 아두이노 1 (Slave) ==> 아두이노 2 (Master)
- (D10) SS ==> (D10) SS
- (D11) MOSI ==> (D11) MOSI
- (D12) MISO ==> (D12) MISO
- (D13) SCLK ==> (D13) SCLK
- GND ==> GND
- 아두이노 1 – 디지털 5번 핀에 LED, 저항을 연결
스케치는 아래와 같이 올립니다.
아두이노 2 MASTER 코드 (데이터 보내는 부분)
#include <SPI.h> void setup (void) { digitalWrite(SS, HIGH); SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV8); } void loop (void) { // enable Slave Select digitalWrite(SS, LOW); // SS is pin 10 // send test string SPI.transfer('1'); // disable Slave Select digitalWrite(SS, HIGH); delay (1000); }
아두이노 1 SLAVE (데이터 받는 부분)
#include <SPI.h> volatile boolean isOn = false; void setup() { // have to send on master in, *slave out* pinMode(MISO, OUTPUT); // turn on SPI in slave mode SPCR |= _BV(SPE); // now turn on interrupts SPI.attachInterrupt(); pinMode(5, OUTPUT); } // SPI interrupt routine ISR (SPI_STC_vect) { byte c = SPDR; // grab byte from SPI Data Register if (c == '1') isOn = true; else isOn = false; // turn on interrupts SPCR |= _BV(SPIE); } void loop() { if(isOn) { digitalWrite(5, HIGH); } else { digitalWrite(5, LOW); } delay(50); }
SPI 통신 라이브러리는 인터럽트 서비스 루틴(ISR) 으로 데이터를 받습니다. 데이터가 오면 ISR 함수가 자동으로 호출됩니다. 따라서 ISR 함수 내부에서 변경하는 전역 변수(isOn)는 volatile 로 선언되어야 합니다.
참고자료
- UART/SoftwareSerial: [출처] [아두이노]아두이노끼리 통신하기
- I2C/TWI: F*CKING COREA, Arduino, Maker’s Diary(by manyonglee)
- http://forum.arduino.cc/index.php?topic=184527.0
- http://www.arduino.cc/en/Tutorial/MasterReader
- http://electronics.stackexchange.com/questions/42197/making-two-arduinos-talk-over-spi
- http://www.gammon.com.au/forum/?id=10892
.
좋은 자료 감사합니다.
하지만 아직 배움이 부족한지 응용이 안되고 있어서 질문 좀 드리겠습니다…
저희가 이번에 학교에서 아두이노를 이용해 뭔가를 하나 해야되는데
버스에 출.입 으로 버스안에 사람이 몇명있나 확인하는걸 만들려하고 있습니다.
입구에는 카운터를 올리는 아두이노 출구에는 카운터를 내리는 그런 방식입니다.
하지만 어떻게 두대의 결과값을 한 화면에 옮기는지 감이 안잡혀서 글을 남깁니다.
조그만한 힌트나 조언을 좀 부탁드립니다 ^^
아두이노 둘을 유무선 방식으로 통신하도록 만들어야 하는데요… 워낙 방법이 많아서 딱 집어 말씀드리기 힘드네요. 위 처럼 유선으로 연결한 뒤 한쪽으로 수집한 데이터가 모이도록 하는 것도 방법이구요. 블루투스 등으로 연결할 수도 있으며.. 아두이노가 많을 경우 HC-11 RF 모듈로 1:N 연결을 만들 수도 있습니다.
둘을 무선으로 연결하는 방법은 어떻게 해야 되나요?.?
일단 데이터를 받는 Slave 쪽에 데이터를 저장하는 변수를 만들고요 마스터에서 1을 보내면 slave에서 1을 감소시키고요 슬레이브에서는 카드를 찍으면 변수값을 1 증가시키면 될듯 합니다
이거 한게의 보드에만 젼류 흘려보내도 다른거 켜 지나요?
핀을 늘리기 위해 아두이노 여러개를 연결하고자 하는데 단방향통신이면 master>(I2C)>SLAVE1>(SPI)>SLAVE2 이런식으로 연결해도 되나요?