CAN 통신

CAN 네트워크 구성 및 다중 노드 통신 실습

임베디드 친구 2025. 2. 27. 10:20
728x90
반응형

CAN 네트워크 구성 및 다중 노드 통신 실습

1. 개요

CAN(Controller Area Network) 통신은 여러 개의 노드를 연결하여 데이터를 주고받을 수 있는 직렬 통신 방식입니다. 자동차, 산업 자동화, 로봇 등의 다양한 분야에서 사용되며, 다중 노드 환경에서 충돌 없이 데이터를 전송할 수 있는 강력한 프로토콜입니다.

이번 포스팅에서는 ESP32 IDF(ESP-IDF) 를 활용하여 여러 개의 노드를 연결하는 방법과 다중 노드 환경에서 메시지를 송수신하는 방법을 실습합니다. 또한, CAN 버스의 부하 테스트 및 충돌 테스트를 진행하여 실전 환경에서 발생할 수 있는 문제를 분석합니다.


2. CAN 네트워크 구성

CAN 네트워크는 여러 개의 노드를 하나의 CAN 버스에 연결하는 방식으로 구성됩니다. CAN 버스는 차동 신호(differential signal) 를 사용하여 노이즈에 강한 통신을 제공합니다.

2.1 하드웨어 구성 요소

  • ESP32 개발 보드 (ESP-IDF 지원) - 2개 이상
  • CAN 트랜시버 (MCP2551 또는 SN65HVD230 등)
  • 120Ω 종단 저항 (각 끝단 1개씩 총 2개 필요)
  • 점퍼 와이어 및 브레드보드

2.2 하드웨어 연결 방법

각 ESP32 보드는 CAN 트랜시버를 통해 서로 연결되며, 트랜시버는 CAN_H 및 CAN_L 핀을 통해 하나의 CAN 버스를 공유합니다.

ESP32 <-> CAN 트랜시버 연결 (SN65HVD230 기준)

ESP32 핀 CAN 트랜시버 핀
GPIO21 TXD
GPIO22 RXD
GND GND
3.3V VCC
CAN_H CAN_H
CAN_L CAN_L

2.3 네트워크 구성

  • 두 개 이상의 ESP32 보드를 하나의 CAN 버스에 연결
  • 각 노드는 CAN 트랜시버를 통해 통신
  • 버스 양쪽 끝에 120Ω 종단 저항을 연결하여 신호 반사를 방지

3. 다중 노드 환경에서 메시지 송수신

CAN 네트워크에서 메시지를 송수신하는 방법을 실습합니다. ESP32 IDF에서 제공하는 TWAI (Two-Wire Automotive Interface) 드라이버 를 사용하여 CAN 메시지를 송수신할 수 있습니다.

3.1 ESP32 CAN 송신 코드

아래 코드는 ESP32 IDF 환경에서 CAN 메시지를 송신하는 코드 입니다.

#include "driver/twai.h"
#include <stdio.h>

void app_main() {
    twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(GPIO21, GPIO22, TWAI_MODE_NORMAL);
    twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
    twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

    twai_driver_install(&g_config, &t_config, &f_config);
    twai_start();

    while (1) {
        twai_message_t message;
        message.identifier = 0x123;
        message.data_length_code = 4;
        message.data[0] = 0x11;
        message.data[1] = 0x22;
        message.data[2] = 0x33;
        message.data[3] = 0x44;

        if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
            printf("Message sent successfully!\n");
        } else {
            printf("Failed to send message.\n");
        }
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

3.2 ESP32 CAN 수신 코드

아래 코드는 ESP32 IDF 환경에서 CAN 메시지를 수신하는 코드 입니다.

#include "driver/twai.h"
#include <stdio.h>

void app_main() {
    twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(GPIO21, GPIO22, TWAI_MODE_NORMAL);
    twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
    twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

    twai_driver_install(&g_config, &t_config, &f_config);
    twai_start();

    while (1) {
        twai_message_t message;
        if (twai_receive(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
            printf("Received message: ID=0x%X, Data=[%02X %02X %02X %02X]\n",
                message.identifier,
                message.data[0], message.data[1],
                message.data[2], message.data[3]);
        }
    }
}

4. CAN 버스 부하 및 충돌 테스트

다중 노드 환경에서 충돌이 발생하는 경우 CAN 버스에서 자동으로 충돌을 감지하고 재전송을 수행합니다. 이를 실험하기 위해 여러 개의 노드에서 동시에 메시지를 송신하는 테스트를 진행할 수 있습니다.

4.1 CAN 충돌 테스트 방법

  1. 3개 이상의 ESP32 노드를 CAN 버스에 연결
  2. 모든 노드에서 같은 ID(예: 0x123)로 메시지를 동시에 송신
  3. 버스에서 충돌이 발생하는지 확인하고 자동 재전송 여부 확인

4.2 충돌 테스트 결과 분석

  • CAN 프로토콜은 CSMA/CD+AMP (Carrier Sense Multiple Access with Collision Detection and Arbitration on Message Priority) 를 사용하여 충돌을 감지하고 메시지를 우선순위에 따라 자동 재전송합니다.
  • 우선순위가 높은 메시지(ID 값이 작은 메시지)가 먼저 전송됨
  • 우선순위가 낮은 메시지는 재전송됨

5. 결론

이번 포스팅에서는 ESP32 IDF를 활용하여 CAN 네트워크를 구성하고 다중 노드에서 메시지를 송수신하는 방법을 실습하였습니다. 또한, CAN 버스 부하 및 충돌 테스트 를 수행하여 실전 환경에서 발생할 수 있는 문제를 분석했습니다.

핵심 정리

  • ESP32와 CAN 트랜시버를 활용하여 다중 노드 통신을 구성
  • ESP32 IDF의 TWAI 드라이버를 활용하여 CAN 메시지를 송수신
  • 다중 노드 환경에서 CAN 충돌 테스트 및 자동 재전송 메커니즘 확인
반응형