Closed3

can通信の勉強

hossyanhossyan

はじめに

昨今のBLDCを扱うにはcan通信が必須らしい
今まではサンプルコードで頑張ってきてたのでそろそろちゃんと理解したい

通信の種類

そもそもマイコンの通信の種類がわかってないので調べます。
chatgptに聞いた感じ以下のようなものが代表的らしい。
通信の仕方(プログラム面)のほうが知りたいのであっさい解釈で行きます。

  • UART
    1対1の通信、マイコンのデバックで使うイメージ RX,TXの二本
  • SPI
    4本の線、高速で通信できるらしい LCDとかに使う
  • I2C
    SPIの2本線版?センサー類で使うイメージがある
    電圧をHIGHにあげるためにもプルアップ抵抗がいる
  • CAN
    差動通信で行う。電圧の出力をIC側で行っているためPWMで調整などではない。ノイズに強い

ほかにもRS485やethernetなどあるけど一旦パス

hossyanhossyan

can通信について

参考文献としてよいものがあったのでそれを添付します。
https://note.com/cute_tern596/n/n8baba3a0f1ee

https://zenn.dev/ryuzot/articles/dc9ba524fbb29e

物理層

2本線になっていて差動通信により0,1の情報を送り付けている
差動通信になるのでノイズに強くなる

データリンク層

送り付けるデータとしては以下のものが挙げられる

  • データフレーム
    • canidを識別する識別子
       拡張フォーマットになると11bitから29bitになる
      信号が衝突したときcanidが若いもののほうが優先される
    • コントロールフィールド : データの長さ
    • データフィールド : 本体
    • CRCフィールド : データの整合性を担保する

↓あんまり使わんからいったんスキップする

  • リモートフレーム
  • エラーフレーム
  • オーバーロードフレーム

ビットタイミング

非同期通信で行っているためクロックを合わせるために工夫がいる
方法があるらしいけど難しかったので一旦パス

hossyanhossyan

プログラムの記載方法

ある程度canを理解してきたので実際に使うためのプログラムのやり方をまとめる。
私の開発環境に対してのアプローチを考える

使用ソフト Visual Stadio Code
環境 platformIO
マイコン M5stack Core2
canモジュール m5stack commu
can変換IC MCP2515-1 / SO

※Core2は標準のm5stackとピン配置が違うため、commuモジュールを取り扱う分には注意がいる。commuモジュールのピンを一本切らないとコンパイルができなくなるなどある。

mcp_canというライブラリを使えば簡単にできるらしいので、これの使い方を学ぶ

can_setup
#include <M5Unified.h>
#include <SPI.h>
#include <mcp_can.h>

// canのデータ配列の作成
unsigned char data[8] = {0};

//can setup
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
#define CAN0_INT 15  //canの受信信号を受け取る
MCP_CAN CAN0(27); //cs pinの設定    

// can初期化
void init_can() {
    if (CAN0.begin(MCP_ANY, CAN_1000KBPS, MCP_8MHZ) == CAN_OK) {
        Serial.println("Success");
    } else {
        Serial.println("Error");
    }
    CAN0.setMode(MCP_NORMAL);
}

void setup() {
    M5.begin();
    M5.Power.begin();

    init_can();
}

場合によってはinit_can()のなかをwhileで回すほうがいいかも

can_send
CAN0.sendMsgBuf(0x200, 0, 8, data);

引数は(id, ext, len, data)となっている。
extとは11bitか29bitのどっちを使うかで0,1で判断する。0なら11bit。
lenはデータ長で基本8byte。dataの書き方は仕様書による。

can_read
 if (CAN0.checkReceive() == CAN_MSGAVAIL) {
    CAN0.readMsgBuf(&rxId, &len, rxBuf);
}

CAN_MSGAVAILはcanのメッセージが来たことを示す定数

このスクラップは2ヶ月前にクローズされました