#初めに
今回は、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にソースコードを書きこみます。
その後シリアルモニタを開きます。
まず、CAN IDを決めます。今回は CAN IDを0x102とします。
(16進数だったら、黄色の矢印のように0x---と入力します。2byteです。)
入力したらEnterで送信します。
そうすると、入力した値の10進数と16進数を表示してきます。
この後は、先ほど入力したCAN IDで送りたいデータを入力します。4byteです。
10進数を入力したいときはこのように入力します。
Enterで送信すると、入力したCAN IDでCANにデータを送信してくれます。
データはビッグエンディアンです。
while(1)で処理しているので、リセットボタンを押さずに続けて使えます。
#終わりに
手元にCANアナライザーがなかったので作りました。
製品には比べ物にならないですが、自分で使う分には十分です。