Avance.Lab

技術紹介

ラズパイからSPIポートを使ってCAN送信する方法

公開日:2024.03.22 更新日:2024.03.22

tag: CANRaspberry Pi車載

こんにちは、MYです。

ラズパイもいろんなことができて便利ですね。
多くの機能を付けたいところですが、機器の組み合わせで、
「ポートが足りない」
「そもそもポートがない」
ということがありますよね?

前回、ソラさんがI2Cポートを使用してのCAN通信を紹介していましたので
私からはSPIポートを使用してのCAN通信を紹介したいと思います。

構成

■機器構成

機器ラズパイ3B+※ラズパイ4Bには対応していません
変換基板  SPI CAN 変換ボードhttps://www.amazon.co.jp/s?k=MCP2515
言語C言語

■CAN構成

CAN通信速度500kbps
CANアダプタKvaser Leaf Light v2    
確認用PC(OS)   Windows10 64bit
確認用ツールCandy自社開発のCANアプリです。
※あとがきに、紹介ページのリンクを記載しておきます。

構成図

環境の構成を下記に示します。

変換基板の改造

ラズパイのSPIは3.3Vなので、MCP2515も3.3Vにて駆動させます。
ただ、KvaserのCAN通信が5Vのため、CANトランシーバを5Vで駆動するように基板を改造します。
変換基板背面のパターンを削り、CANトランシーバに3.3Vが給電されないようにします。

上の構成図に記したオレンジの線のようにCANトランシーバへ5Vを給電します。

ラズパイの設定

SPI CAN変換ボード(MCP2515)を使用するために
/boot/config.txt に以下の設定を追加します。

# MCP2515 CAN module
dtparm=spi=on
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=25
dtoverlay=spi-dcm2835

「oscillator=8000000」でSPI CAN変換ボードの発振周波数を設定します。
「interrupt=25」でINTに使用するGPIOを設定します。

config.txtを変更したら、ラズパイを再起動してください。

ソースコード

ソースコードを記載します。

linuxのCANクラスを使用して、SPIポートから送信します。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/can.h>
#include <linux/can/raw.h>

#define CAN_NAME "can0"

/*** メイン ***/
void main(void)
{
  int32_t sock;
  struct ifreq ifr;
  int32_t loopback = 1;
  
  struct sockaddr_can addr;
  struct can_frame frame;
  
  // ソケット OPEN
  sock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
  
  strncpy(ifr.ifr_name, CAN_NAME, sizeof(ifr.ifr_name));

  ifr.ifr_ifindex = if_nametoindex(ifr.ifr_name);

  addr.can_family = AF_CAN;
  addr.can_ifindex = ifr.ifr_ifindex;
  loopback = 0; 
  setsockopt(sock, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &loopback, sizeof(loopback));

  bind(sock, (struct sockaddr *)&addr, sizeof(addr));  
  
  // 送信データの作成
  frame.can_id = 0x80; // CANID
  frame.can_dlc = 8;   // CANデータサイズ
  frame.data[0] = 0x11; // 送信データ1
  frame.data[1] = 0x22; // 送信データ2
  frame.data[2] = 0x33; // 送信データ3
  frame.data[3] = 0x44; // 送信データ4
  frame.data[4] = 0x55; // 送信データ5
  frame.data[5] = 0x66; // 送信データ6
  frame.data[6] = 0x77; // 送信データ7
  frame.data[7] = 0x88; // 送信データ8

  // データ送信
 write(sock, &frame, CAN_MTU);

  // ソケット CLOSE
  close(sock);
}

通信速度の設定

CAN通信のビットレートを500kbpsに設定します。

$sudo ip link set can0 down
$sudo ip link set can0 type can bitrate 500000
$sudo ip link set can0 up

コンパイルと動作確認

コンパイルし、実行ファイルを起動します。

$gcc -o spi_test spi_test.c
$./spi_test

実行結果

CANデータを取得するツールで値を確認し、
送信したデータが取得できていることを確認できました。

あとがき

ラズパイからSPIポートを使ってCAN通信の確認ができました。
今回使用した変換基板以外にも便利な変換基板はいろいろ販売されています。
興味がある方は、探してみるのはどうでしょうか。

確認に使用した自社開発ツールのCandyは、以下で紹介しています。

第1回 Candy 〜 メッセージ送受信 〜https://avancesys.co.jp/laboratory/article/%e7%ac%ac1%e5%9b%9e-candy-%e3%80%9c-%e3%83%a1%e3%83%83%e3%82%bb%e3%83%bc%e3%82%b8%e9%80%81%e5%8f%97%e4%bf%a1-%e3%80%9c/
第2回 Candy 〜 通信設定 〜https://avancesys.co.jp/laboratory/article/%e7%ac%ac2%e5%9b%9e-candy-%e3%80%9c-%e9%80%9a%e4%bf%a1%e8%a8%ad%e5%ae%9a-%e3%80%9c/
第3回 Candy 〜 ログ記録 〜https://avancesys.co.jp/laboratory/article/%e7%ac%ac3%e5%9b%9e-candy-%e3%80%9c-%e3%83%ad%e3%82%b0%e8%a8%98%e9%8c%b2-%e3%80%9c/
YM
YM

Windowsアプリや組み込みを担当しています。

関連記事