2019年1月19日土曜日

ESP-WROOM-32でCAN BUSを使ってみる

ESP-WROOM-32にはSJA1000互換のCANコントローラーが内蔵されているのでCANトランシーバーだけ用意すればCAN BUSが使えるっぽい。
ArduinoでCANって言うとMCP2515っていうCANコントローラーのライブラリがとても情報量が多くて使いやすいんだけど、MCP2515とSJA1000の両方に対応しているライブラリがあったのでそちらを使ってみた。

使用させてもらったライブラリはこちら。
どうやらESP32で使うとSJA1000、Atmega328pなどのArduinoだとMCP2515を使えるようになっているライブラリっぽい。サンプルも入っているので助かった。
関数がほぼ同じなのでESP32以外に移植するときもかんたんに移植できそう。

あとはCANトランシーバーが必要なんだけど、ESP-WROOM-32は3.3V駆動なので3.3V駆動のSN65HVD232Dを用意した。本当はスタンバイ端子とかあったほうがいいらしいんだけど面倒なので…
このICはD(1番ピン)をGPIO5、R(4番ピン)をGPIO4につないであとは電源をESP32と共通の3.3VにつなぐだけでOK。

Raspberry PiにMCP2515つないでCANのデータを見れるようにしたかったんだけどまたMCP2515が届いてないので本当にCAN BUSでデータ送受信できてるかの検証がいまだできず…
とりあえずInnovate LC-2をAEMnetにつなげそうなサンプルプログラムを書いてみた。ただしデータの送信頻度はMTS依存だし足りないデータがあるからだめかも?


#include <CAN.h>

#define LED_BUILTIN 2

int Lambda[4];
int Func[4];
byte CanData[8]={0x00,0x00,0x00,0x00,0x0C,0x0C,0x82,0x02};
boolean isSend = true;

void setup() {
  Serial.begin(115200);
  Serial2.begin(19200, SERIAL_8N1, 16, 17);//RX 16, TX 17
  pinMode(LED_BUILTIN,OUTPUT);

  CAN.setPins(4, 5);
  CAN.begin(500E3);
}

void loop() {
  serialEvent2();
  if (!isSend){
    if(Func[0] == 0){
      int lambda = ((Lambda[0]+500)*10);//Lambda x10000
      CanData[0] = highByte(lambda);
      CanData[1] = lowByte(lambda);
      can_send();
    }
  }
}

void serialEvent2() {
  while (Serial2.available() > 0) {
    byte mtshead[2];
    Serial2.readBytes(mtshead,1);
    if((mtshead[0] & 0xA2) == 0xA2){
      //debug
      mtshead[1] = mtshead[0];
      Serial2.readBytes(mtshead,1);
      if((mtshead[1] & 0x80) == 0x80){
        digitalWrite(LED_BUILTIN, HIGH);
        int stream_len = int(((mtshead[1] & 0x01) << 7) | (mtshead[0] & 0x7F));
        int sense_cnt = 0;
        for (int i=1; i <= stream_len; ++i){
          byte mtsdata[2];
          Serial2.readBytes(mtsdata,2);
          if((mtsdata[0] & 0x42) == 0x42){
            isSend = false;
            Lambda[sense_cnt] = int(((mtsdata[0] & 0x01) << 7) | (mtsdata[1] & 0x7F));
            Func[sense_cnt] = int((mtsdata[0] & 0x34) >> 2);
            sense_cnt++;
            Serial.println(Func[sense_cnt]);
          }
        }
        return;
      }else{
        return;
      }
    }else{
      return;
    }
  }
}

void can_send(){
  CAN.beginExtendedPacket(384);
  for (int i=0; i <= 7; i++){
    CAN.write(CanData[i]);
  }
  CAN.endPacket();
  isSend = true;
  digitalWrite(LED_BUILTIN, LOW);
}

今回は送信だけのテストプログラムだけど、ライブラリでは受信もできるのでソフト次第でELM327を使わずにOBD2でECUと通信できるかも。
オープンソースのELM327互換デバイスとかもあるみたいだし、ここらへん移植できたらBluetoothとかWiFi接続のアダプタが作れちゃったり。

MCP2515のボードいつ届くのかなぁ
安いのでArduino用買ってしまったから5V品っぽいんだけど、Raspberry Piで使うためにCANトランシーバー張り替えるかパターンカットでCANトランシーバーにだけ5V入れるかか…
3.3V対応のCANトランシーバもう少し買っておくんだった…
続きはテスト環境が届いてからかな

ちなみにESP32にCANトランシーバをつけずにこのライブラリを使用するとフリーズするというか無限ループに入ってしまうみたい。タイムアウトとか設定できるといいんだけども…

0 件のコメント:

コメントを投稿