質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.61%

ArduinoでCAN受信

受付中

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 5,004

score 10

前提・実現したいこと

ECUとArduinoを用いて、CAN通信を行うプログラムを作成しています。
ここで、Arduino側でCAN受信プログラムを作成していますが、正しく受信できません。

発生している問題・エラーメッセージ

作成したプログラムでは、データの中身を受信することが出来ません。
(以下参照)

ID: 0 Data: 
ID: 0 Data: 
ID: 0 Data: 
ID: 0 Data: 
ID: 0 Data: 
ID: 0 Data: 
ID: 0 Data: 
・・・

該当のソースコード

//CAN受信
//受信画面をシリアルで送信

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

//設定値
#define CS_PIN  (10)
#define INT_PIN (9)

long unsigned int rxId;
unsigned char len =0;
unsigned char rxBuf[8];

MCP_CAN CAN0(CS_PIN);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  CAN0.begin(CAN_STDID, CAN_500KBPS, MCP_8MHZ); // CANの通信速度を500kbpsにする 
  pinMode(INT_PIN,INPUT);
  CAN0.setMode(MCP_NORMAL); //??
  Serial.println("CAN受信テスト");
}

void loop() {
  // put your main code here, to run repeatedly:
  if(!digitalRead(INT_PIN))
  {
    CAN0.readMsgBuf(&rxId,&len,rxBuf);
    //rxId = CAN0.getCanId();
    Serial.print("ID: ");
    Serial.print(rxId, HEX);
    Serial.print(" Data: ");
    for(int i = 0; i<len; i++)
    {
      if(rxBuf[i] < 0x10)
      {
        Serial.print("0");
      }
      Serial.print(rxBuf[i], HEX);
      Serial.print(" ");
    }
    Serial.println();
  }
}

試したこと

mcp_can.h の中身などを調査。
CANの調査。
Seeed社のサイトの調査。
http://wiki.seeedstudio.com/CAN-BUS_Shield_V2.0/

補足情報(FW/ツールのバージョンなど)

Arduino UNO, seeed製 CAN-BUS Shield を使用。
ECU側で送信できることは確認済み。
ターミナルブロックがワンタッチ式で使い方に若干不安あり。

サイトなどを読み、少し変えて動かしてみたものになります。
プログラムの十分な理解はまだ出来ていません。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • y_waiwai

    2019/01/31 14:18

    ECUってだけでは意味不明です。詳しい型番を提示しましょう。
    んで、Arduinoのなにを使ってますか?
    また、回路図も必要です

    キャンセル

回答 3

0

まず手順が少し足らないと思います。
気になる部分は参考のページリンク内容
の右側のAPIの説明の部分に
INT8U MCP_CAN :: checkReceive(void);
でまず受信の確認。
INT32U MCP_CAN :: getCanId(void)
で送信先のIDの取得。

この辺と思われます。
まずは一読を。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

CAN0.beginの返り値はCAN_OKですか?
多分違うと思います。

私も同じ環境でCAN通信をしていますが、引数は(CAN_500KBPS, MCP_16MHZ);の2つで行っています。
あなたの第一引数についてはよくわかりません。。。

CANシールドの銀色部分に16.00と書かれていると思います。
それがクロック周波数なので引数をMCP_16MHZとしてください。

自分も初心者なので詳しいことはわかりませんが、これで解決すると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

まず、部分部分でデバッグできるようにしてはどうでしょうか?

スケッチ例を確認して、どのようにすればエラーの確認ができるかわかると思います。
ここに示す方法もスケッチ例からのコピペです。

あなた⇒

  Serial.begin(9600);
  CAN0.begin(CAN_STDID, CAN_500KBPS, MCP_8MHZ); // CANの通信速度を500kbpsにする 

提案例⇒

  Serial.begin(9600);
  Serial.print("Begin CAN Training  => ");
  // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
  if(CAN1.begin(MCP_ANY, CAN_500KBPS, MCP_16MHZ) == CAN_OK) Serial.println("MCP2515 No.1 Initialized Successfully!");
  else Serial.println("Error Initializing MCP2515 No.1...");
  CAN1.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted
コード

あなた⇒

  if(!digitalRead(INT_PIN))
  {
    CAN0.readMsgBuf(&rxId,&len,rxBuf);
    Serial.print("ID: ");
    Serial.print(rxId, HEX);
    Serial.print(" Data: ");
    for(int i = 0; i<len; i++)
    {
      if(rxBuf[i] < 0x10)
      {
        Serial.print("0");
      }
      Serial.print(rxBuf[i], HEX);
      Serial.print(" ");
    }
    Serial.println();

提案例⇒

  if(!digitalRead(INT_PIN1))                         // If CAN2_INT pin is low, read receive buffer
  {
    CAN2.readMsgBuf(&CAN2Id, &len, rxBuf);      // Read data: len = data length, buf = data byte(s)

    if((CAN2Id & 0x80000000) == 0x80000000)     // Determine if ID is standard (11 bits) or extended (29 bits)
      sprintf(msgString, "  Extended ID: 0x%.8lX  ", (CAN2Id & 0x1FFFFFFF));
    else
      sprintf(msgString, "  Standard ID: 0x%.3lX       ", CAN2Id);
    Serial.print("Message Recieved Successfully! =>");
    Serial.println(msgString);
    sprintf(msgString, "DLC: %1d  Data:", len);
    Serial.print(msgString);
    //Serial.print("  DLC: %1d  Data:", len);
    if((CAN2Id & 0x40000000) == 0x40000000){    // Determine if message is a remote request frame.
      sprintf(msgString, " REMOTE REQUEST FRAME");
      Serial.print(msgString);
    } else {
      for(byte i = 0; i<len; i++){
        sprintf(msgString, " 0x%.2X", rxBuf[i]);
        Serial.print(msgString);
      }
    }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る