1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Arduino Uno互換機でCAN送信機を作ってみた(4byte送信)

Last updated at Posted at 2021-08-03

#初めに
今回は、CAN(Controller Area Network)通信の受信テストをするときに必要なCAN送信機をArduino Uno互換機で作ってみました。

私は、4byteの送信しか必要なかったので、4byteしか送信できません。

github:https://github.com/Yu-Tomo/CAN_test_sender

#概要
Arudino IDEからシリアルモニタを使ってCAN IDとデータを決めて送信します。
データの順番は、ビッグエンディアンです。

10進数入力と16進数入力に対応しています。

0x~~と書くと16進数になります。10進数はいつも通りです。
0sなどと書くとバグになります。テスト用なので悪しからず。

#使用するIC

使用するICはおなじみの、MCP2515とMCP2561です。

#回路
基本的な配線は、色々なサイトに記載されているため、割愛します。

#ソースコード

使用しているCANライブラリは、https://github.com/sandeepmistry/arduino-CAN から使わせてもらっています。

#define CAN_CS 6
#define CAN_INT 2

ソースコードの上の部分を、お使いのマイコンに合わせて変更してください。

#define CAN_CS 6
#define CAN_INT 2

#include <CAN.h>
#include <string.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
  Serial.println("CAN sender start!");
}
void loop() {
  uint16_t uiCan_id;
  int iByte;
  long lCan_data;
  unsigned char ucSend[4];
  uint8_t ucWork;
  
  while (1)
  {
    uiCan_id = 0;
    iByte = 0;
    lCan_data = -1;
    ucWork = 0;

    for (int i = 0; i < 4; i++)
    {
      ucSend[i] = 0;
    }
    
    Serial.println("Please input CAN_ID : ");
    uiCan_id = SerialInput();
    Serial.print("OK! Your inputing is (DEC) : ");
    Serial.print(uiCan_id);
    Serial.print(" (HEX) : 0x");
    Serial.println(uiCan_id, HEX);

    while (!((lCan_data >= 0 ) && (lCan_data <= 0x7FFFFFFF)))
    {
      Serial.println("Please input your sending data :");
      lCan_data = SerialInput();
    }

    Serial.print("OK! Your inputing is (DEC) : ");
    Serial.println(lCan_data);
    Serial.print("Your inputing is (HEX) : ");
    Serial.print("0x");
    Serial.println(lCan_data, HEX);

    for (int i = 3 ; i >= 0; i--)
    {
      ucWork = lCan_data >> 8 * (3-i);
      ucSend[i] = ucWork;
    }
    Serial.println("Big Endian");
    Serial.println("Sending packet ... ");
    CAN.beginPacket(uiCan_id);
    for (int i = 0; i < 4; i++)
    {
      CAN.write(ucSend[i]);
      Serial.print("0x");
      Serial.println(ucSend[i], HEX);
    }
    CAN.endPacket();
    Serial.println("done");
    delay(1000);
  }
}
long SerialInput(void)
{
  int iByte_cnt = 0;
  long work = 0;
  char ucData[256];
  char dec_hex = 1;         //0以外の時dec
  while (!Serial.available())
  {

  }
  delay(10);
  
  iByte_cnt = Serial.available();
  
  for (int i = 0; i < iByte_cnt; i++)
  {
    ucData[i] = Serial.read();
  }
  
  //改行コードがOSによって異なるため、有効文字の数を数える
  iByte_cnt = String_len(&ucData[0]);
  dec_hex = strncmp(ucData, "0x", 2);

  //入力がHEX
  if (dec_hex == 0)
  {
    Serial.println("HEX ");

    for (int i = 2; i < iByte_cnt; i++)
    {
      work <<= 4;
      if ((ucData[i] >= '0') && (ucData[i] <= '9'))
      {
        //'0'~'9'をHEXに変換
        work |= (ucData[i] - 0x30);
      }
      else if ((ucData[i] >= 'A') && (ucData[i] <= 'F'))
      {
        //'A'~'F'をHEXに変換
        work |= (ucData[i] - 0x37);
      }
      else if ((ucData[i] >= 'a') && (ucData[i] <= 'f'))
      {
        //'a'~'f'をHEXに変換
        work |= (ucData[i] - 0x57);
      }
      else
      {
        //異常終了
        return -1;
      }
    }
  }
  //入力がDEC
  else
  {
    Serial.println("DEC");
    for (int i = 0; i < iByte_cnt; i++)
    {
      work *= 10;
      work += (ucData[i] - 0x30);
    }
  }
  return work;
}
int String_len(char* str)
{
  int iCnt = 0;
  while ((*str >= 0x30 ) && (*str <= 0x7a))
  {
    str++;
    iCnt++;
  }
  return iCnt;
}

#使い方

CAN通信用ICを取り付けたArduino Unoにソースコードを書きこみます。
その後シリアルモニタを開きます。

SharedScreenshot.jpg
この画面になります。

SharedScreenshot2.jpg

まず、CAN IDを決めます。今回は CAN IDを0x102とします。
(16進数だったら、黄色の矢印のように0x---と入力します。2byteです。)
入力したらEnterで送信します。

SharedScreenshot3.jpg

そうすると、入力した値の10進数と16進数を表示してきます。

この後は、先ほど入力したCAN IDで送りたいデータを入力します。4byteです。

SharedScreenshot4.jpg

10進数を入力したいときはこのように入力します。

SharedScreenshot5.jpg

Enterで送信すると、入力したCAN IDでCANにデータを送信してくれます。
データはビッグエンディアンです。

while(1)で処理しているので、リセットボタンを押さずに続けて使えます。

#終わりに
手元にCANアナライザーがなかったので作りました。
製品には比べ物にならないですが、自分で使う分には十分です。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?