こんにちは、ソラです。
ラズパイもいろんなことができて便利ですね。
多くの機能を付けたいところですが、機器の組み合わせで、
「ポートが足りない」
「そもそもポートがない」
ということがありますよね?
そんなときは、変換基板を使用して違う機能のポートから対応することができます。
今回は、その一つとして、I2Cポートを使用して、CAN送信をしたいと思います。
■機器構成
機器 | ラズパイ4B | |
変換基板 | I2C CAN 変換ボード | https://www.switch-science.com/products/7437 |
言語 | C言語 |
■CAN構成
CAN通信速度 | 500kbps | 変換基板モジュールのデフォルト設定をそのまま使用します。 ※変更したい場合は、仕様に基づき、アドレスと通信速度を送り、設定してください。 |
CANアダプタ | Kvaser Leaf Light v2 | |
確認用PC(OS) | Windows10 64bit | |
確認用ツール | Candy | 自社開発のCANアプリです。 ※あとがきに、紹介ページのリンクを記載しておきます。 |
環境の構成を下記に示します。
ソースコードを記載します。
CAN送信データ(CANID、DLC、DATA、チェックサム)をバッファへセットします。
linuxのI2Cデバイスクラスを使用して、I2Cポートから送信します。
CAN送信データは、I2C CAN 変換モジュールの仕様により、16バイト分のデータで、
最後はチェックサムが必須になります。
【メイン関数】
CAN送信データの作成と送信を行います。
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#define DEV_NAME = "/dev/i2c-1"
int8_t i2c_send(uint8_t dev_addr, uint8_t reg_addr, const uint8_t* data, uint16_t length);
int8_t makeCheckSum(int8_t *dta, int8_t len);
/*** メイン ***/
void main(void)
{
int8_t ret;
uint8_t send_data[16];
// 送信データの作成
send_data[0] = 0;
send_data[1] = 0;
send_data[2] = 0;
send_data[3] = 0x80; // CANID
send_data[4] = 0;
send_data[5] = 0;
send_data[6] = 8; // CANデータサイズ
send_data[7] = 0x11; // 送信データ1
send_data[8] = 0x22; // 送信データ2
send_data[9] = 0x33; // 送信データ3
send_data[10] = 0x44; // 送信データ4
send_data[11] = 0x55; // 送信データ5
send_data[12] = 0x66; // 送信データ6
send_data[13] = 0x77; // 送信データ7
send_data[14] = 0x88; // 送信データ8
send_data[15] = get_check_sum(send_data,15); // チェックサム
// データ送信
ret = i2c_send(0x25, 0x30, send_data, 16);
}
【データ送信関数】
送信したいデータをI2Cで送信します。
/*** I2Cスレーブデバイスにデータ送信 ***/
int8_t i2c_send(uint8_t dev_addr, uint8_t reg_addr, const uint8_t* data, uint16_t length)
{
// I2Cデバイスをオープンする
int32_t fd = open(DEV_NAME, O_RDWR);
if (fd == -1)
{
return FALSE;
}
// I2C-Write用のバッファを準備する
uint8_t* buffer = (uint8_t*)malloc(length + 1);
if (buffer == NULL)
{
close(fd);
return FALSE;
}
buffer[0] = reg_addr; // 1バイト目にレジスタアドレスをセット
memcpy(&buffer[1], send_data, length); // 2バイト目以降にデータをセット
// I2C-Writeメッセージを作成する
struct i2c_msg message = { dev_addr, 0, length + 1, buffer };
struct i2c_rdwr_ioctl_data ioctl_data = { &message, 1 };
// I2C-Writeを行う
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 1)
{
free(buffer);
close(fd);
return FALSE;
}
free(buffer);
close(fd);
return TRUE;
}
【チェックサム関数】
送信データに必要な、チェックサムを作成します。
/*** チェックサム計算 ***/
static uint8_t get_check_sum(uint8_t *data, uint8_t len)
{
unsigned long sum = 0;
for(int i=0; i<len; i++)
{
sum += (data[i] & 0xff);
}
if(sum > 0xff)
{
sum = ~sum;
sum += 1;
}
sum = sum & 0xff;
return (uint8_t)sum;
}
コンパイルし、実行ファイルを起動します。
$gcc -o i2c_test i2c_test.c
$./i2c_test
CANデータを取得するツールで値を確認し、
送信したデータが取得できていることを確認できました。
ラズパイのI2Cポートを使ってCAN通信の確認ができました。
今回の変換に限らず、他にも変換して通信する方法は、多々あると思います。
興味がある方は、探してみるのはどうでしょうか。
確認に使用した自社開発ツールのCandyは、以下で紹介しています。
関連記事
-
第1回 ラズパイを使用したBLE通信 ~ ディスプレイ、キーボード、マウスを接続しないで設定 前編 ~
こんにちは、GTです。よろしくお願いします。 最近業務でラズパイのBluetooth機能を使...
公開日:2021.12.24 更新日:2021.12.24
tag : Bluetooth Raspberry Pi
-
-
第1回 Visual C++で作成したDLL内のクラスをC#で利用する方法
こんにちは、ILCです。 Visual C++ (以下 VC++)で作成されたDynamic...
公開日:2024.01.19 更新日:2024.01.19
tag : Windows
-
-
こんにちは、TMIHです。 今回から組み込み系のソフトウェア設計標準規格である、MISRA-...
公開日:2022.02.25 更新日:2022.02.25
-
第3回 ラズパイを使用したBLE通信 ~ A/D変換・D/A変換を用いた入出力編 ~
こんにちは、GTです。よろしくお願いします。 第3回の今回は、ラズパイの入出力についてご紹介...
公開日:2023.02.24 更新日:2023.02.24
tag : Bluetooth BLE Raspberry Pi