본문 바로가기
-----ETC-----/C++ 임베디드 시스템 프로그래밍 시리즈

[C++ 임베디드 시스템 프로그래밍 시리즈] Day 18: CAN 통신

by cogito21_cpp 2024. 8. 1.
반응형

CAN 통신의 개요

CAN(Controller Area Network) 통신은 차량 내부의 여러 전자 제어 장치 간의 데이터 통신을 위해 개발된 직렬 통신 프로토콜입니다. CAN은 높은 신뢰성과 빠른 데이터 전송 속도를 제공하여 자동차, 산업 자동화, 의료 기기 등에서 널리 사용됩니다. 오늘은 CAN 통신의 기본 개념과 사용 방법을 학습하겠습니다.

1. CAN 통신의 기본 개념

CAN 통신은 다음과 같은 특징을 가집니다:

  • 멀티마스터/슬레이브 구조: 여러 마스터와 슬레이브 장치가 동시에 통신할 수 있습니다.
  • 메시지 기반 프로토콜: 각 메시지는 고유의 식별자(ID)를 가지며, 네트워크 상의 모든 장치가 메시지를 수신할 수 있습니다.
  • 고속 데이터 전송: 최대 1Mbps의 데이터 전송 속도를 제공합니다.
  • 오류 검출 및 처리: 높은 신뢰성을 보장하기 위해 다양한 오류 검출 및 처리 메커니즘을 포함합니다.

2. CAN 통신 설정

CAN 통신을 사용하려면 CAN 컨트롤러와 트랜시버가 필요합니다. Arduino에서는 MCP2515 CAN 컨트롤러와 MCP2551 트랜시버를 사용하여 CAN 통신을 구현할 수 있습니다.

3. CAN 통신 사용 예제

다음 예제에서는 두 개의 Arduino 보드를 사용하여 CAN 통신을 구현하는 방법을 보여줍니다. 하나의 보드는 송신기로, 다른 보드는 수신기로 설정하여 데이터를 송수신합니다.

 

하드웨어 연결

  1. Arduino 1 (송신기):
    • VCC: 5V
    • GND: GND
    • CS: 10번 핀
    • SO: 12번 핀
    • SI: 11번 핀
    • SCK: 13번 핀
    • CANH: Arduino 2의 CANH에 연결
    • CANL: Arduino 2의 CANL에 연결
  2. Arduino 2 (수신기):
    • VCC: 5V
    • GND: GND
    • CS: 10번 핀
    • SO: 12번 핀
    • SI: 11번 핀
    • SCK: 13번 핀
    • CANH: Arduino 1의 CANH에 연결
    • CANL: Arduino 1의 CANL에 연결

MCP_CAN 라이브러리 설치

MCP2515 CAN 컨트롤러를 사용하려면 MCP_CAN 라이브러리를 설치해야 합니다.

  1. Arduino IDE 라이브러리 매니저 열기:
    • Sketch -> Include Library -> Manage Libraries...
  2. 라이브러리 검색 및 설치:
    • MCP_CAN을 검색하고, MCP_CAN 라이브러리를 설치합니다.

예제: 송신기 코드 (Arduino 1)

#include <SPI.h>
#include <mcp_can.h>

const int SPI_CS_PIN = 10;
MCP_CAN CAN(SPI_CS_PIN);

void setup() {
    Serial.begin(115200);
    if (CAN.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK) {
        Serial.println("CAN BUS Shield init ok!");
    } else {
        Serial.println("CAN BUS Shield init fail");
        while (1);
    }
    CAN.setMode(MCP_NORMAL);
}

void loop() {
    byte data[8] = {'H', 'e', 'l', 'l', 'o', '!', ' ', ' '};
    CAN.sendMsgBuf(0x00, 0, 8, data);
    Serial.println("Message sent: Hello!");
    delay(1000);
}

 

예제: 수신기 코드 (Arduino 2)

#include <SPI.h>
#include <mcp_can.h>

const int SPI_CS_PIN = 10;
MCP_CAN CAN(SPI_CS_PIN);

void setup() {
    Serial.begin(115200);
    if (CAN.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK) {
        Serial.println("CAN BUS Shield init ok!");
    } else {
        Serial.println("CAN BUS Shield init fail");
        while (1);
    }
    CAN.setMode(MCP_NORMAL);
}

void loop() {
    unsigned char len = 0;
    unsigned char buf[8];

    if (CAN_MSGAVAIL == CAN.checkReceive()) {
        CAN.readMsgBuf(&len, buf);
        Serial.print("Message received: ");
        for (int i = 0; i < len; i++) {
            Serial.print((char)buf[i]);
        }
        Serial.println();
    }
}

 

위 코드에서는 첫 번째 Arduino 보드가 송신기로 설정되어 데이터를 송신하고, 두 번째 Arduino 보드가 수신기로 설정되어 데이터를 수신하여 시리얼 모니터에 출력합니다.

 

마무리

오늘은 CAN 통신을 사용하여 데이터를 송수신하는 방법을 학습했습니다. 두 아두이노 간의 CAN 통신을 통해 CAN 통신의 기본 개념과 활용 방법을 익혔습니다. 다음 날에는 블루투스 통신에 대해 더 깊이 알아보겠습니다.

질문이나 추가적인 피드백이 있으면 언제든지 댓글로 남겨 주세요.

Day 19 예고

다음 날은 "블루투스 통신"에 대해 다룰 것입니다. 블루투스를 사용하여 데이터를 송수신하는 방법을 학습하고, 실습 예제를 통해 이해를 돕겠습니다.

반응형