주요 콘텐츠

이 페이지는 기계 번역을 사용하여 번역되었습니다. 영어 원문을 보려면 여기를 클릭하십시오.

CAN 통신에서 DBC 파일 사용

이 예제는 DBC 파일에 저장된 정보를 사용하여 메시지를 생성, 수신 및 처리하는 방법을 보여줍니다. 이 예시는 CAN 네트워크의 워크플로를 설명하지만, 제시된 개념은 CAN FD 네트워크에도 적용됩니다.

DBC 파일 열기

canDatabase를 사용하여 demoVNT_CANdbFiles.dbc 파일을 엽니다.

db = canDatabase("demoVNT_CANdbFiles.dbc")
db = 
  Database with properties:

             Name: 'demoVNT_CANdbFiles'
             Path: 'C:\Users\michellw\OneDrive - MathWorks\Documents\MATLAB\Examples\vnt-ex80654288\demoVNT_CANdbFiles.dbc'
            Nodes: {}
         NodeInfo: [0×0 struct]
         Messages: {5×1 cell}
      MessageInfo: [5×1 struct]
       Attributes: {}
    AttributeInfo: [0×0 struct]
         UserData: []

Messages 속성을 확인하여 이 파일에 정의된 모든 메시지의 이름을 볼 수 있습니다.

db.Messages
ans = 5×1 cell
    {'DoorControlMsg'   }
    {'EngineMsg'        }
    {'SunroofControlMsg'}
    {'TransmissionMsg'  }
    {'WindowControlMsg' }

메시지 정보 보기

messageInfo를 사용하여 메시지 EngineMsg의 식별자, 데이터 길이 및 신호 목록을 포함한 정보를 확인하십시오.

messageInfo(db, "EngineMsg")
ans = struct with fields:
             Name: 'EngineMsg'
     ProtocolMode: 'CAN'
          Comment: ''
               ID: 100
         Extended: 0
            J1939: []
           Length: 8
              DLC: 8
              BRS: 0
          Signals: {2×1 cell}
       SignalInfo: [2×1 struct]
          TxNodes: {0×1 cell}
       Attributes: {}
    AttributeInfo: [0×0 struct]

모든 메시지에 대한 정보를 한 번에 쿼리할 수도 있습니다.

messageInfo(db)
ans=5×1 struct array with fields:
    Name
    ProtocolMode
    Comment
    ID
    Extended
    J1939
    Length
    DLC
    BRS
    Signals
    SignalInfo
    TxNodes
    Attributes
    AttributeInfo

신호 정보 보기

메시지 EngineMsg 내 신호 EngineRPM의 정보를 확인하려면 signalInfo를 사용하십시오. 여기에는 유형, 바이트 순서, 크기 및 원시 신호를 물리적 값으로 변환하는 스케일링 값이 포함됩니다.

signalInfo(db, "EngineMsg", "EngineRPM")
ans = struct with fields:
             Name: 'EngineRPM'
          Comment: ''
         StartBit: 0
       SignalSize: 32
        ByteOrder: 'LittleEndian'
           Signed: 0
        ValueType: 'Integer'
            Class: 'uint32'
           Factor: 0.1000
           Offset: 250
          Minimum: 250
          Maximum: 9500
            Units: 'rpm'
       ValueTable: [0×1 struct]
      Multiplexor: 0
      Multiplexed: 0
    MultiplexMode: 0
          RxNodes: {0×1 cell}
       Attributes: {}
    AttributeInfo: [0×0 struct]

메시지 EngineMsg 내의 모든 신호에 대한 정보를 한 번에 쿼리할 수도 있습니다.

signalInfo(db, "EngineMsg")
ans=2×1 struct array with fields:
    Name
    Comment
    StartBit
    SignalSize
    ByteOrder
    Signed
    ValueType
    Class
    Factor
    Offset
    Minimum
    Maximum
    Units
    ValueTable
    Multiplexor
    Multiplexed
    MultiplexMode
    RxNodes
    Attributes
    AttributeInfo
      ⋮

데이터베이스 정의를 사용하여 메시지 생성하기

데이터베이스와 메시지 이름 EngineMsg를 지정하여 새 메시지를 생성하면 데이터베이스 정의가 적용됩니다. 이 메시지의 CAN 신호는 원시 데이터 바이트 외에도 공학 단위로 표시됩니다.

msgEngineInfo = canMessage(db, "EngineMsg")
msgEngineInfo = 
  Message with properties:

   Message Identification
    ProtocolMode: 'CAN'
              ID: 100
        Extended: 0
            Name: 'EngineMsg'

   Data Details
       Timestamp: 0
            Data: [0 0 0 0 0 0 0 0]
         Signals: [1×1 struct]
          Length: 8

   Protocol Flags
           Error: 0
          Remote: 0

   Other Information
        Database: [1×1 can.Database]
        UserData: []

신호 정보 보기

Signals 속성을 사용하여 이 메시지의 신호 값을 확인하십시오. 이러한 신호에 직접 쓰기 및 읽기를 수행하여 메시지에서 데이터를 패킹하거나 언패킹할 수 있습니다.

msgEngineInfo.Signals
ans = struct with fields:
    VehicleSpeed: 0
       EngineRPM: 250

신호 정보 변경하기

신호 EngineRPM에 직접 쓰기를 수행하여 그 값을 변경하십시오.

msgEngineInfo.Signals.EngineRPM = 5500.25
msgEngineInfo = 
  Message with properties:

   Message Identification
    ProtocolMode: 'CAN'
              ID: 100
        Extended: 0
            Name: 'EngineMsg'

   Data Details
       Timestamp: 0
            Data: [23 205 0 0 0 0 0 0]
         Signals: [1×1 struct]
          Length: 8

   Protocol Flags
           Error: 0
          Remote: 0

   Other Information
        Database: [1×1 can.Database]
        UserData: []

현재 신호 값을 다시 읽고, EngineRPM가 쓰여진 값으로 업데이트되었음을 확인하십시오.

msgEngineInfo.Signals
ans = struct with fields:
    VehicleSpeed: 0
       EngineRPM: 5.5003e+03

값이 신호에 직접 쓰여질 때, 해당 값은 데이터베이스 정의를 사용하여 메시지 데이터로 변환, 스케일링 및 패킹됩니다. VehicleSpeed 신호에 새 값이 쓰여진 후 Data 속성의 값 변화에 유의하십시오.

msgEngineInfo.Signals.VehicleSpeed = 70.81
msgEngineInfo = 
  Message with properties:

   Message Identification
    ProtocolMode: 'CAN'
              ID: 100
        Extended: 0
            Name: 'EngineMsg'

   Data Details
       Timestamp: 0
            Data: [23 205 0 0 71 0 0 0]
         Signals: [1×1 struct]
          Length: 8

   Protocol Flags
           Error: 0
          Remote: 0

   Other Information
        Database: [1×1 can.Database]
        UserData: []

msgEngineInfo.Signals
ans = struct with fields:
    VehicleSpeed: 71
       EngineRPM: 5.5003e+03

데이터베이스 정보가 포함된 메시지 수신하기

CAN 채널에 데이터베이스를 연결하여 수신 메시지에 데이터베이스 정의를 자동으로 적용합니다. 데이터베이스는 정의된 메시지만 디코딩합니다. 다른 모든 메시지는 원시 형태로 수신됩니다.

rxCh = canChannel("MathWorks", "Virtual 1", 2);
rxCh.Database = db
rxCh = 
  Channel with properties:

   Device Information
            DeviceVendor: 'MathWorks'
                  Device: 'Virtual 1'
      DeviceChannelIndex: 2
      DeviceSerialNumber: 0
            ProtocolMode: 'CAN'

   Status Information
                 Running: 0
       MessagesAvailable: 0
        MessagesReceived: 0
     MessagesTransmitted: 0
    InitializationAccess: 1
        InitialTimestamp: [0×0 datetime]
           FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All'

   Channel Information
               BusStatus: 'N/A'
              SilentMode: 0
         TransceiverName: 'N/A'
        TransceiverState: 'N/A'
       ReceiveErrorCount: 0
      TransmitErrorCount: 0
                BusSpeed: 500000
                     SJW: []
                   TSEG1: []
                   TSEG2: []
            NumOfSamples: []

   Other Information
                Database: [1×1 can.Database]
                UserData: []

메시지 수신하기

채널을 시작하고, 메시지 트래픽을 생성하며, 물리적 메시지 디코딩을 통해 메시지를 수신합니다.

start(rxCh);
generateMsgsDb();
rxMsg = receive(rxCh, Inf, "OutputFormat", "timetable");

수신된 메시지의 처음 몇 줄을 확인하세요.

head(rxMsg)
ans=8×8 timetable
       Time        ID     Extended            Name                       Data              Length      Signals       Error    Remote
    ___________    ___    ________    _____________________    ________________________    ______    ____________    _____    ______

    0.13103 sec    100     false      {'EngineMsg'        }    {[     0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.13103 sec    200     false      {'TransmissionMsg'  }    {[     0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.13104 sec    400     false      {'DoorControlMsg'   }    {[     0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.13104 sec    600     false      {'WindowControlMsg' }    {[             0 0 0 0]}      4       {1×1 struct}    false    false 
    0.13105 sec    800     false      {'SunroofControlMsg'}    {[                 0 0]}      2       {1×1 struct}    false    false 
    0.15598 sec    100     false      {'EngineMsg'        }    {[     0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.18 sec       100     false      {'EngineMsg'        }    {[172 129 0 0 50 0 0 0]}      8       {1×1 struct}    false    false 
    0.18001 sec    200     false      {'TransmissionMsg'  }    {[     4 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 

수신 채널을 중지하고 작업 공간에서 제거하십시오.

stop(rxCh);
clear rxCh

수신된 메시지 검토하기

수신된 메시지를 검사하여 적용된 데이터베이스 디코딩을 확인하십시오.

rxMsg(10, :)
ans=1×8 timetable
       Time        ID     Extended        Name                   Data              Length      Signals       Error    Remote
    ___________    ___    ________    _____________    ________________________    ______    ____________    _____    ______

    0.22994 sec    100     false      {'EngineMsg'}    {[172 129 0 0 50 0 0 0]}      8       {1×1 struct}    false    false 

rxMsg.Signals{10}
ans = struct with fields:
    VehicleSpeed: 50
       EngineRPM: 3.5696e+03

지정된 메시지의 모든 인스턴스 추출하기

메시지 EngineMsg의 모든 인스턴스를 추출하십시오.

allMsgEngine = rxMsg(strcmpi("EngineMsg", rxMsg.Name), :);

이 특정 메시지의 처음 몇 개 사례를 확인하세요.

head(allMsgEngine)
ans=8×8 timetable
       Time        ID     Extended        Name                   Data              Length      Signals       Error    Remote
    ___________    ___    ________    _____________    ________________________    ______    ____________    _____    ______

    0.13103 sec    100     false      {'EngineMsg'}    {[     0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.15598 sec    100     false      {'EngineMsg'}    {[     0 0 0 0 0 0 0 0]}      8       {1×1 struct}    false    false 
    0.18 sec       100     false      {'EngineMsg'}    {[172 129 0 0 50 0 0 0]}      8       {1×1 struct}    false    false 
    0.20597 sec    100     false      {'EngineMsg'}    {[172 129 0 0 50 0 0 0]}      8       {1×1 struct}    false    false 
    0.22994 sec    100     false      {'EngineMsg'}    {[172 129 0 0 50 0 0 0]}      8       {1×1 struct}    false    false 
    0.25695 sec    100     false      {'EngineMsg'}    {[172 129 0 0 50 0 0 0]}      8       {1×1 struct}    false    false 
    0.27995 sec    100     false      {'EngineMsg'}    {[172 129 0 0 50 0 0 0]}      8       {1×1 struct}    false    false 
    0.30597 sec    100     false      {'EngineMsg'}    {[172 129 0 0 50 0 0 0]}      8       {1×1 struct}    false    false 

물리적 신호 값 플로팅하기

canSignalTimetable를 사용하여 메시지 EngineMsg의 신호 데이터를 신호 타임테이블로 리패키징합니다.

signalTimetable = canSignalTimetable(rxMsg, "EngineMsg");

신호 타임테이블의 처음 몇 줄을 확인하십시오.

head(signalTimetable)
ans=8×2 timetable
       Time        VehicleSpeed    EngineRPM
    ___________    ____________    _________

    0.13103 sec          0             250  
    0.15598 sec          0             250  
    0.18 sec            50          3569.6  
    0.20597 sec         50          3569.6  
    0.22994 sec         50          3569.6  
    0.25695 sec         50          3569.6  
    0.27995 sec         50          3569.6  
    0.30597 sec         50          3569.6  

시간에 따른 신호 VehicleSpeed의 값을 그래프로 표시하십시오.

plot(signalTimetable.Time, signalTimetable.VehicleSpeed)
title("Vehicle Speed from EngineMsg", "FontWeight", "bold")
xlabel("Timestamp")
ylabel("Vehicle Speed")

DBC 파일 닫기

작업 공간에서 DBC 파일의 변수를 지워 해당 파일에 대한 액세스를 종료하십시오.

clear db