목차
[아두이노] 1:1 캔통신 연결하기: 준비
이번 실습에서는 MCP2515 CAN 통신 트랜시버를 사용하여 아두이노 보드 간의 1대1 통신을 진행할 것입니다. MCP2515는 Controller Area Network (CAN) 프로토콜을 지원하는 트랜시버로, 자동차 및 산업용 기기에서 널리 사용되는 통신 방식입니다.
먼저, 아두이노 프로그래밍을 위해 아래 웹사이트에서 MCP2515 라이브러리를 zip 파일로 다운로드 받습니다. 이 라이브러리는 아두이노와 MCP2515 모듈 간의 통신을 용이하게 해주며, 송수신 코드를 구현하는 데 필요한 함수들을 포함하고 있습니다.
https://github.com/autowp/arduino-mcp2515
실습에서는 두 아두이노 우노 보드를 사용합니다. 하나는 송신측으로, 다른 하나는 수신측으로 설정됩니다. 송신측에서는 수신측의 ID와 데이터 길이(DLC, Data Length Code) 값을 전송합니다. 이 정보는 CAN 프레임의 일부로, 수신측이 올바른 데이터를 수신하고 해석할 수 있도록 합니다.
수신측 아두이노는 별도의 필터링 없이 CAN 버스 라인 상의 모든 데이터를 읽습니다. CAN 시스템에서 데이터는 프레임 형식으로 전송되며, 각 프레임에는 식별자(ID)와 데이터 필드가 포함됩니다.
이 실습을 위해 필요한 재료는 다음과 같습니다.
- 2개의 아두이노 우노 보드
- 2개의 MCP2515 CAN 통신 모듈
- 다수의 점퍼 케이블
아두이노 보드와 MCP2515 모듈의 핀 연결은 아래와 같습니다.
- D2 → INT (인터럽트)
- D13 → SCK (시리얼 클록)
- D12 → SO (시리얼 아웃)
- D11 → SI (시리얼 인)
- D10 → CS (칩 셀렉트)
두 MCP2515 모듈은 서로 High(H) 핀은 High(H)끼리, Low(L) 핀은 Low(L)끼리 연결해야 합니다. 이 연결은 모듈 간의 통신을 가능하게 하며, 안정적인 데이터 전송을 보장합니다.
[아두이노] 1:1 캔통신 연결하기: 실습
1. 라이브러리를 ZIP 파일로 아두이노에 추가하면 아래와 같이 예제 파일이 만들어 집니다.
2. 아두이노 보드 하나에는 CAN_write를 프로그램 하고 다른 하나는 CAN_read를 프로그램 합니다. 각 각의 코드는 아래와 같습니다.
CAN_write 코드>>
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg1;
struct can_frame canMsg2;
MCP2515 mcp2515(10);
void setup() {
canMsg1.can_id = 0x0F6; //슬레이브1의 ID
canMsg1.can_dlc = 8;
canMsg1.data[0] = 0x8E;
canMsg1.data[1] = 0x87;
canMsg1.data[2] = 0x32;
canMsg1.data[3] = 0xFA;
canMsg1.data[4] = 0x26;
canMsg1.data[5] = 0x8E;
canMsg1.data[6] = 0xBE;
canMsg1.data[7] = 0x86;
canMsg2.can_id = 0x036; //슬레이브2의 ID
canMsg2.can_dlc = 8;
canMsg2.data[0] = 0x0E;
canMsg2.data[1] = 0x00;
canMsg2.data[2] = 0x00;
canMsg2.data[3] = 0x08;
canMsg2.data[4] = 0x01;
canMsg2.data[5] = 0x00;
canMsg2.data[6] = 0x00;
canMsg2.data[7] = 0xA0;
while (!Serial);
Serial.begin(115200);
mcp2515.reset();
mcp2515.setBitrate(CAN_125KBPS);
mcp2515.setNormalMode();
Serial.println("Example: Write to CAN");
}
void loop() {
mcp2515.sendMessage(&canMsg1);
mcp2515.sendMessage(&canMsg2);
Serial.println("Messages sent");
delay(500);
}
위 코드는 2개의 캔 메세지를 0.5초 단위로 전송합니다. 각 메세지는 8바이트 사이즈이고 ID는 코드를 참조하시면 됩니다.
캔 속도는 125kbps로 설정되었습니다.
CAN_read 코드>>
#include <SPI.h>
#include <mcp2515.h>
struct can_frame canMsg;
MCP2515 mcp2515(10);
void setup() {
Serial.begin(115200);
mcp2515.reset();
mcp2515.setBitrate(CAN_125KBPS);
mcp2515.setNormalMode();
Serial.println("------- CAN Read ----------");
Serial.println("ID DLC DATA");
}
void loop() {
if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
Serial.print(canMsg.can_id, HEX); // print ID
Serial.print(" ");
Serial.print(canMsg.can_dlc, HEX); // print DLC
Serial.print(" ");
for (int i = 0; i<canMsg.can_dlc; i++) { // print the data
Serial.print(canMsg.data[i],HEX);
Serial.print(" ");
}
Serial.println();
}
}
3. 아래와 같이 수신측의 Serial Monitoring을 통해 정상적으로 캔 메세지를 출력함을 알 수 있습니다.
'아두이노 Arduino' 카테고리의 다른 글
[아두이노] 일정 시간 간격으로 시리얼 출력하기(Arduino, millis, delay, 1초) (0) | 2024.01.08 |
---|---|
아두이노 데이터 타입 크기 탐색: 시리얼 모니터 출력 예제 실습(Arudino, Data type, uint_8, uint_16) (2) | 2023.11.25 |
[아두이노] 파이썬 Pyserial로 Blink 예제 실행하기 (PC to Arduino) (2) | 2022.05.12 |
[아두이노] String함수: indexof, substring, length (텍스트 검색, 위치 찾기) (0) | 2022.05.11 |
[아두이노]1초마다 프로그램 동작 시키기(millis(),delay(), scheduling, 스케쥴링) (0) | 2022.05.10 |