こんにちは、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回 Visual C++で作成したDLL内のクラスをC#で利用する方法
こんにちは、ILCです。 Visual C++ (以下 VC++)で作成されたDynamic...
公開日:2024.01.19 更新日:2024.01.19
tag : Windows
-
-
-
第1回 ラズパイを使用したBLE通信 ~ ディスプレイ、キーボード、マウスを接続しないで設定 前編 ~
こんにちは、GTです。よろしくお願いします。 最近業務でラズパイのBluetooth機能を使...
公開日:2021.12.24 更新日:2021.12.24
tag : Bluetooth Raspberry Pi
-
【新機能探訪】Android 13から導入された『アプリごとの言語設定』
こんにちは、KNSKです。よろしくお願いします。 今回は Android13の新機能である『...
公開日:2022.12.09 更新日:2022.12.09
tag : スマートデバイス
-
こんにちは。WwWです。 システム系の開発をしていると様々な問題が起こります。 そこで今回は...
公開日:2023.04.28 更新日:2023.04.28