84motのアイコン画像
84mot 2022年09月25日作成 (2022年09月26日更新)
製作品 製作品 閲覧数 838
84mot 2022年09月25日作成 (2022年09月26日更新) 製作品 製作品 閲覧数 838

Spresenseで家庭の消費電力値をスマートメータから取得してEVの充電を制御するデバイス

概要

SONYのSpresenseとROHMのWI-SUN拡張モジュールを使って家庭のスマートメータ―から現在の消費電力値を取得して、EVなどの大電力消費デバイスの使用可否を判断できるデバイスを作りました。

解決したいこと

最近アーク溶接機を購入しましたが、いざ家で溶接しようとすると気になるのが消費電力。
どれくらい電力を使っているか正直よくわかっていません。
いつも恐る恐る使っていますが、自宅で使用しているEVの充電タイミングとかち合ってブレーカー落すなんて事は回避したい。(家ではデスクトップで仕事もしていることですし)

欲しいもの

しかしながら 「今我が家はどれくら電力を消費しているのか」 を把握するのはかなりハードルが高い。
そしてブレーカーを落とす前に優先度の低い機器のスイッチを切ってほしい。←EVの充電とか。
それも自動で。

どうやって実現するか

Spresenseを基本として以下を追加して構成。
  WI-sun拡張ボード (家庭用スマート電力メーターからの瞬間電力値取得用)
  リレー (充電コードの根本を直接ON/OFFする)
これであれば既存のEV充電器にリレーをかまして、心置きなく溶接を楽しめるようなシステムが作れるはず!

以下がその構成図

構成図

が、実際に作成したものは大きく変更が入りました。

~背景(という名の言い訳)~
開発にあたり真っ先にWI-SUN経由でスマートメータから電力情報を取得するところから取り掛かりました。
が・・・想像の100倍大変でした。

基本的にはハードさえあれば、後は自宅の管轄の電力会社からもらえるメーター接続用のIDとパスワードがあれば必要なものは揃います。
これはスムーズに入手できました。
が、その後のソフト開発で難航‥‥。

ハードのWI-SUNボードの製造元(ROHM)のサンプルコードはあるのですが、それは拡張ボードを子機(スマートメータ側)として使用する場合のコードとなっていました。(←これに気づくのにも時間がかかった…)
拡張ボード”から”メーターにアクセスする際のサンプルコードを見つける事ができず、結局用途違いではありますが前述のROHMのサンプルコードをベースに組みなおしました。
スマートメータ接続用のプロトコルであるECHONET-Liteも馴染みが薄く、情報収集もなかなか進まない中で仕様書とにらめっこしながら実装を進める事10日間。
なんとか瞬時電力値の取得に成功しました!というのが締め切り2日前。。。

実際に作成した構成図は以下の通り。

実際に作った構成図

動作

WI-sun拡張ボードがスマートメータ―から常時消費電力値を取得。
家全体の消費電力が一定の数値を超えるとサーボを駆動して車の模型からEV充電プラグを外して充電禁止をユーザーに通知。
一定以内であれば電力消費量に余裕ありとして車の模型に充電プラグを接続して、充電OKをユーザーに通知。
溶接を行なう時もEVの充電プラグが模型と同じ状態かを確認すれば、ブレーカーを飛ばす事も無い・・・はず。

以下の様な瞬時電力値のグラフが取得できます。(1秒間隔)
瞬時電力値[W]

参考URL

まさか情報集でもこんなに苦労するとは…という状況の中で最終的に輝いていた仕様書を記載します。

ECHONET規格団体
https://echonet.jp/spec_object_rq/

細かい通信仕様(ここの理解が超重要)
https://echonet.jp/spec_v113_lite/

ROHM(Wi-SUNのIC製造元)が出しているスマートメータと接続するためのコマンドやり取り。
これが神の様な役割を果たし、電力値の取得までいけました。感謝。
※これ見て実装するだけ…と言えばその通りなんですが、ハードもソフトもハマリポイント多し)
https://fscdn.rohm.com/jp/products/databook/applinote/module/wireless/bp35c0-j11_b-route_an-j.pdf

プログラム

最後にプログラムを記載しておきます。
※デバッグ分も多いため非常に長いプログラムとなってしまっていますがご勘弁ください

今回はArduino IDEで開発しました。
以下の3ファイルで構成されています。
・main.ino
   シーケンス制御を主として行なう。
   state=0から始まり、state=9で瞬時電力の取得を繰り返す

・SPRESENSE-WISUN-EVK-701_84mota-2.ino
   メインの処理。
   コマンドの送信、応答の処理など。

・bp35c0-j11.h
   Wi-SUNやECHONET-Liteに関係するコマンドなどの定義。

#define DEBUG のコメント/コメントアウトによりSerial上に各種状態などが大量に出力されます。

SPRESENSE-WISUN-EVK-701_84mota-2.ino

/*
  SPRESENSE-WISUN-EVK-701
  Copyright (c) 2019 ROHM Co.,Ltd.

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
*/
#include "bp35c0-j11.h"
//#define DEBUG
#define DEBUG2





unsigned char state = 0;
unsigned char state_past = 0;



BP35C0J11 bp35c0j11;

void setup() {
  boolean rc = FALSE ;
  bp35c0j11.j11_init();
  rc = bp35c0j11.wait_msg();
#ifdef DEBUG
  Serial.println("wait_mes() 通過");
  Serial.print("rc=");
  Serial.println(rc);
#endif
  if (rc == TRUE) {
    state = 1 ;           //  hardware reset end
  } else {
    state = 0 ;
  }

  //シリアルモニタ用
  Serial.println("瞬時電力 [W]");
  s_servo.write(90);

//サーボ駆動用
    s_servo.attach(PIN_D03);
  s_servo.write(80);
  
}

void loop() {

  unsigned char msg_length = 0 ;
  boolean rc = 0 ;

#ifdef DEBUG
  //  Serial.println(" ");
  //  Serial.print("State = ");
  //  Serial.println(state, DEC);
#endif

  delay(500);
  
#ifdef DEBUG2
if(state != state_past){
  Serial.print("state=");
  Serial.println(state);
}
state_past = state;
#endif

  switch (state) {
    case (0):  // need hardware reset
      rc = bp35c0j11.cmd_send(CMD_RESET);
      rc = bp35c0j11.wait_msg();
      if (rc == TRUE) {
        state = 1 ;
      }
      break;
    case (1): //  init state
      rc = bp35c0j11.cmd_send(CMD_INI);
      rc = bp35c0j11.wait_msg();
      if (rc == TRUE) {
        state = 2;
      }
      break;
    case (2): //B-root 接続初期設定


      //Bルート接続認証ステータスを追加 ここから
      rc = bp35c0j11.cmd_send(CMD_B_ROOT_INI);
      rc = bp35c0j11.wait_msg();
      if (rc == TRUE) {
        state = 3;
      }
      break;

    //Bルート接続認証ステータスを追加 ここまで

    case (3): // active scan
      rc = bp35c0j11.cmd_send(CMD_SCAN);
      rc = bp35c0j11.wait_msg();

      if (rc == TRUE) {
        rc = bp35c0j11.wait_msg();

      }

      break;
    case (4): // スキャン結果をBルート設定にフィードバック

      rc = bp35c0j11.cmd_send(CMD_INI2);
      rc = bp35c0j11.wait_msg();
      if (rc == TRUE) {
        state = 5;
#ifdef DEBUG
        Serial.println("スキャン結果の取り込み完了");
#endif DEBUG
      }
      break;
    case (5): // Bルート動作開始要求
      rc = bp35c0j11.cmd_send(CMD_B_ROOT_ACTIVE);
      rc = bp35c0j11.wait_msg();

      if (rc == TRUE) {
#ifdef DEBUG
        Serial.println("Bルート動作を開始します");
#endif DEBUG
        state = 6;
      }

      break;
    case (6): // UDPポートOPEN要求
      rc = bp35c0j11.cmd_send(CMD_PORTOPEN);
      rc = bp35c0j11.wait_msg();
      if (rc == TRUE) {
#ifdef DEBUG
        Serial.println("status を7に変更");
#endif DEBUG
        state = 7;

      }
      break;
    case (7): // PANA認証開始
      rc = bp35c0j11.cmd_send(CMD_B_ROOT_PANA);
      rc = bp35c0j11.wait_msg();
      if (rc == TRUE) {
        rc = bp35c0j11.wait_msg();
        if (rc == TRUE) {
          rc = bp35c0j11.wait_msg();
          if (rc == 1) {
#ifdef DEBUG
            Serial.println("PANA認証開始応答を確認。state を8に変更");
#endif DEBUG
            state = 8;
          } else {
#ifdef DEBUG
            Serial.println("PANA認証開始応答を確認できませんでした。再起動します。");
#endif DEBUG
            state = 0;
          }
        }
      }
      break;


    case (8):
      //スマートメータ―応答値の定義を確認する。
      //動作状態、係数、積算電力量有効桁数、積算電力量単位


      rc = bp35c0j11.cmd_send(CMD_UDPSEND );
      rc = bp35c0j11.wait_msg();
      if (rc == TRUE) {
#ifdef DEBUG
        Serial.println("データ送信要求 完了");
        Serial.println("メーターからの応答待ち");
#endif DEBUG
        rc = bp35c0j11.wait_msg();
        if (rc == TRUE) {
#ifdef DEBUG
          Serial.println("statusを9に変更");
#endif DEBUG
          state = 9;
        } else
        {
          state = 0;

          Serial.println("メーターからの応答がタイムアウトしたため再起動します");

        }

      } else {

        Serial.println("データ送信要求 失敗");

        state = 8;
      }
      break;


    case (9):
      //■■■計測時刻付きで積算電力計測値を取得する(30分ごと更新値)■■■
      //■■■瞬時電力値、瞬時電流値を取得する■■■

      rc = bp35c0j11.cmd_send(CMD_UDPSEND );
      rc = bp35c0j11.wait_msg();
      if (rc == TRUE) {
#ifdef DEBUG
        Serial.println("データ送信要求 完了");
        Serial.println("メーターからの応答待ち");
#endif DEBUG
        rc = bp35c0j11.wait_msg();
        if (rc == TRUE) {
#ifdef DEBUG
          Serial.println("全シーケンス終了。再度計測します");
#endif DEBUG
          state = 9;
        } else {

          Serial.println("メーターからの応答がタイムアウトしたため再要求を実施します");

        }
      } else {

        Serial.println("データ送信要求 失敗");
      }
      break;

    default :
      break;

  }




}

bp35c0-j11.cpp

/********************************************************************************
  bp35c0-j11.cpp
  Copyright (c) 2019 ROHM Co.,Ltd.

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files (the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions:

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.
*********************************************************************************/
#include <Arduino.h>
#include "bp35c0-j11.h"


//#define DEBUG
unsigned const char uni_req[4] = {0xD0 , 0xEA , 0x83 , 0xFC};//Wi-SUNコマンド デバイスへの要求コマンド定義
unsigned const char uni_res[4] = {0xD0 , 0xF9 , 0xEE , 0x5D};//Wi-SUNコマンド デバイスからの応答コマンド定義

unsigned const char ini_data[4] = {0x05 , 0x00 , 0x04 , 0x00};       // Dual(Bルート&HAN) /Sleep 非対応/922.9MHz/20mW出力
unsigned const char scan_CMD[6] = {0x06, 0x00, 0x03, 0xFF, 0xF0, 0x01}; // Active Scan 設定 >> スキャン時間 9.65ms*64 , 4~17CHスキャン, Paring ID 有り の設定

unsigned char pair_id[8] = {0};   // 接続先MACアドレス
unsigned char pan_id[2]; // スマートメータ PAN ID
unsigned char scan_ch[1]; //スキャンした結果スマートメーターからの応答のあったチャンネルを格納する


unsigned  char IPv6_adr[16] = {0}; // 接続先IPv6アドレス スキャンした際にスマートメータ―からの応答を格納する
unsigned const char my_port[2] = { 0x0E , 0x1A };     // オープンするUDPポート
unsigned const char dist_port[2] = { 0x0E , 0x1A };   // 送信先UDPポート

//電力会社から送られてきた情報をそのまま打ち込む
//b_root_id → 認証ID
unsigned const char b_root_id[32] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',}; // //Bルート認証IDをフル桁
unsigned const char password[12] = { 'A' , 'B' , 'C' , 'D' , 'E', 'F' , 'G', 'H' , 'I' , 'J' , 'K' , 'L' };    // パスワード12桁


float Watt = 0 ; //瞬時電力値 [W]
float Watt_th = 1000; // 瞬時電力値からEV充電可否判断のための閾値 [W]

//サーボ駆動用

int start_time = 0;
int change_time = 500; // サーボの角度遷移時間 [ms]

CMD_FORMAT cmd_format;

BP35C0J11::BP35C0J11(void)
{

}

/********************************************************************************
    Name     : j11_init
    Function : initial setting bp35c0-j11
    input    : -
    return   : -
*********************************************************************************/
void BP35C0J11::j11_init(void) {

  // configure output D20/D21
  pinMode(PIN_ENABLE, OUTPUT);
  pinMode(PIN_RESET, OUTPUT);
  digitalWrite(PIN_ENABLE, HIGH);

  delay(1000);

  // Serial port initial
  Serial2.begin(115200);
  Serial.begin(115200);

#ifdef DEBUG
  Serial.write("RESET");
  Serial.println("");
#endif

  digitalWrite(PIN_RESET, LOW);     // reset
  delay(500);
  digitalWrite(PIN_RESET, HIGH);

}

/********************************************************************************
    Name     : wait_msg
    Function : wait for response from bp35c0-j11
    input    : -
    return   : TRUE/FALSE
*********************************************************************************/
boolean BP35C0J11::wait_msg(void)
{
  unsigned long start_time;
  unsigned long current_time;
  unsigned char rcvdata[128] = {0} ;
  unsigned char cnt = 0 ;
  start_time = millis();
  while (Serial2.available() == 0)
  {
    current_time = millis();
    if ((current_time - start_time) > TIMEOUT) {
      Serial.println("receive timeout -> hardware reest");
      state = 0;
      return FALSE;

    }

  }
  while (Serial2.available() > 0 ) {
    delay(5);
    rcvdata[cnt] = Serial2.read();

#ifdef DEBUG
    if (cnt == 0) {
      Serial.print(" res=");
    }
    Serial.print(rcvdata[cnt] , HEX);
    Serial.print(" ");
#endif

    cnt++;
    if (cnt >= 128) {
      Serial.println("receive data over flow");
      return FALSE;
    }
  }

#ifdef DEBUG
  Serial.println("");
#endif

  if (rcvdata[0] == uni_res[0] && rcvdata[1] == uni_res[1] &&
      rcvdata[2] == uni_res[2] && rcvdata[3] == uni_res[3]) {     // RESPONSE/NORTIFICATION
    switch (rcvdata[4] << 8 | rcvdata[5]) {

      case (RES_B_ROOT):
        if (rcvdata[12] == 0x01) {
#ifdef DEBUG
          Serial.println("B-ROOT認証設定 Success");
#endif

        } else {
          Serial.println("B-ROOT認証設定 Error");
          return FALSE;
        }

      case (NORT_WAKE):
#ifdef DEBUG
        Serial.println("起動完了通知受信");
#endif
        break;
      case (RES_INI):
        if (rcvdata[12] == 0x01) {
#ifdef DEBUG
          Serial.println("初期化 成功");
#endif
        } else {
#ifdef DEBUG
          Serial.println("初期化 失敗");
#endif
          return FALSE;
        }
        break;


      case (RES_PANA_SET):
        if (rcvdata[12] == 0x01) {
#ifdef DEBUG
          Serial.println("PANA Password 設定 成功");
#endif
        } else {
#ifdef DEBUG
          Serial.println("PANA Password 設定 失敗");
#endif
          return FALSE;
        }
        break;


      case (CMD_B_ROOT_INI):
        if (rcvdata[12] == 0x01) {
#ifdef DEBUG
          Serial.println("Bルート情報認証設定 完了");
#endif
        } else {
#ifdef DEBUG
          Serial.println("Bルート情報認証設定 失敗");
#endif
          return FALSE;
        }
        break;

      case (RES_SCAN):
        break;

      case (NORT_SCAN):

        if (rcvdata[12] == 0x00) {
#ifdef DEBUG
          Serial.print(" スキャン応答有り★");
          Serial.print(" ch[hex]:");
          Serial.println(rcvdata[13], HEX);
#endif


          //スキャンされたchを格納
          scan_ch[0] = rcvdata[13];
#ifdef DEBUG
          Serial.print(" 応答台数:");
          Serial.println(rcvdata[14]);

          Serial.print(" スマートメータMACアドレス[hex]:");
          Serial.print(rcvdata[15], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[16], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[17], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[18], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[19], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[20], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[21], HEX);
          Serial.print(" ");
          Serial.println(rcvdata[22], HEX);
#endif

          //スキャンされたMACアドレスを格納
          pair_id[0] = rcvdata[15];
          pair_id[1] = rcvdata[16];
          pair_id[2] = rcvdata[17];
          pair_id[3] = rcvdata[18];
          pair_id[4] = rcvdata[19];
          pair_id[5] = rcvdata[20];
          pair_id[6] = rcvdata[21];
          pair_id[7] = rcvdata[22];

#ifdef DEBUG
          Serial.print(" スマートメータPAN ID[hex]:");
          Serial.print(rcvdata[23], HEX);
          Serial.print(" ");
          Serial.println(rcvdata[24], HEX);
#endif

          //スキャンされたPANアドレスを格納
          pan_id[0] = rcvdata[23];
          pan_id[1] = rcvdata[24];

#ifdef DEBUG
          Serial.print(" 受信強度[dBm]:");
          Serial.println((rcvdata[25] - 152) - 104, DEC);

          Serial.println ("スキャンに応答したデバイスが発見されたため接続を試みます");
#endif

          state = 4; //次のステータスへ移行

          //        Serial.println("ステータスを4に変更");

        } else {
#ifdef DEBUG
          Serial.print(" スキャン応答なし");
          Serial.print(" ch[hex]:");
          Serial.println(rcvdata[13], HEX);
#endif
        }
        break;

      case (RES_B_ROOT_Active):

        if (rcvdata[12] == 0x01) {
#ifdef DEBUG
          Serial.println(" Bルート動作開始 成功");

          Serial.print(" 接続ch[hex]:");
          Serial.println(rcvdata[13], HEX);

          Serial.print(" 接続PAN ID[hex]:");
          Serial.print(rcvdata[14], HEX);
          Serial.print(" ");
          Serial.println(rcvdata[15], HEX);


          Serial.print(" 接続MACアドレス[hex]:");
          Serial.print(rcvdata[16], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[17], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[18], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[19], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[20], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[21], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[22], HEX);
          Serial.print(" ");
          Serial.println(rcvdata[23], HEX);

          Serial.print(" 受信強度[dBm]:");
          Serial.println((rcvdata[24] - 152) - 104, DEC);
#endif

          return true;
        } else {
          Serial.println(" Bルート動作応答 失敗");
          return false;
        }
        break;

      case (RES_B_ROOT_PANA):
        if (rcvdata[12] == 0x01) {
#ifdef DEBUG
          Serial.println("PANA開始応答 成功");
#endif

        } else {
          Serial.println("PANA開始応答 失敗");
          return FALSE;
        }
        break;


      case (RES_HAN):
        if (rcvdata[12] == 0x01) {
#ifdef DEBUG
          Serial.println("Bルート応答 成功");
#endif
        } else {
          Serial.println("Bルート応答 失敗");
          return FALSE;
        }
        break;


      case (NORT_PANA):
        if (rcvdata[12] == 0x01) {
#ifdef DEBUG
          Serial.println("PANA 認証成功");

          Serial.print(" 認証先MACアドレス[hex]:");
          Serial.print(rcvdata[13], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[14], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[15], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[16], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[17], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[18], HEX);
          Serial.print(" ");
          Serial.print(rcvdata[19], HEX);
          Serial.print(" ");
          Serial.println(rcvdata[20], HEX);
#endif


        } else {
          Serial.println("PANA 認証失敗");
          return FALSE;
        }
        break;


      case (RES_PORTOPEN):
        if (rcvdata[12] == 0x01) {
#ifdef DEBUG
          Serial.println("UDP port open 成功");
#endif
        } else {
          Serial.println("UDP port open 失敗");
          return FALSE;
        }
        break;



      case (RES_COM_STATUS):
#ifdef DEBUG
        Serial.println(" ");
        Serial.print("スマートメータIPv6アドレス[hex]:");
#endif
        for (int i = 12; i < 28; i++) {
#ifdef DEBUG
          Serial.print(rcvdata[i], HEX);
          Serial.print(" ");
#endif
          IPv6_adr[i - 12] = rcvdata[i]; // IPv6アドレスを格納
        }
#ifdef DEBUG
        Serial.println(" ");
        Serial.print("送信元ポート番号[hex]:");
#endif
        for (int i = 28; i < 30; i++) {
#ifdef DEBUG
          Serial.print(rcvdata[i], HEX);
          Serial.print(" ");
#endif
        }
#ifdef DEBUG
        Serial.println(" ");
        Serial.print("送信先ポート番号[hex]:");
#endif
        for (int i = 30; i < 32; i++) {
#ifdef DEBUG
          Serial.print(rcvdata[i], HEX);
          Serial.print(" ");
#endif
        }
#ifdef DEBUG
        Serial.println(" ");
        Serial.print("送信元PAN ID[hex]:");
#endif
        for (int i = 32; i < 34; i++) {
#ifdef DEBUG
          Serial.print(rcvdata[i], HEX);
          Serial.print(" ");
#endif
        }
#ifdef DEBUG
        Serial.println(" ");
        Serial.print("送信先アドレス種別[hex]:");
#endif
        for (int i = 34; i < 35; i++) {
#ifdef DEBUG
          Serial.print(rcvdata[i], HEX);
          Serial.print(" ");
#endif
        }
#ifdef DEBUG
        Serial.println(" ");
        Serial.print("暗号化有無[hex]:");
#endif
        for (int i = 35; i < 36; i++) {
#ifdef DEBUG
          Serial.print(rcvdata[i], HEX);
          Serial.print(" ");
#endif
        }
#ifdef DEBUG
        Serial.println(" ");
        Serial.print("受信データサイズ[Byte]:");
#endif
        for (int i = 36; i < 38; i++) {
#ifdef DEBUG
          Serial.print(rcvdata[i], DEC);
          Serial.print(" ");
#endif
        }
#ifdef DEBUG
        Serial.println(" ");
        Serial.print("受信データ[hex]:");
#endif
        for (int i = 38; i < rcvdata[36] << 8 | rcvdata[37]; i++) {
#ifdef DEBUG
          Serial.print(rcvdata[i], HEX);
          Serial.print(" ");
#endif
          if (i > 50) {
#ifdef DEBUG
            Serial.println("");
            Serial.print("桁数が50桁を超えたので高速化のため表示をキャンセルします");
#endif
            i = rcvdata[36] << 8 | rcvdata[37] ;
          }
        }
#ifdef DEBUG
        Serial.println(" ");
#endif


        //■■■受信データをフォーマットに従って分解して表示する■■■

        if (state == 8) {
#ifdef DEBUG
          //スマートメータ―応答値の定義を確認する。
          //動作状態、係数、積算電力量有効桁数、積算電力量単位

          //動作状態
          Serial.print("■動作状態[hex] (0x30 でON状態):");
          Serial.println(rcvdata[53], HEX);

          //係数
          Serial.print("■係数:");
          Serial.println(rcvdata[56] << 8 * 3 | rcvdata[57] << 8 * 2 | rcvdata[58] << 8 * 1 | rcvdata[59]);

          //積算電力量有効桁数
          Serial.print("■積算電力量有効桁数:");
          Serial.println(rcvdata[62]);

          //積算電力量単位
          Serial.print("■積算電力量単位(0x00:1kWh , 0x01:0.1kWh, ...:");
          Serial.println(rcvdata[65], HEX);
#endif

        } else if (state == 9) {
          //■■■計測時刻付きで積算電力計測値を取得する(30分ごと更新値)■■■
          //■■■瞬時電力値、瞬時電流値を取得する■■■


#ifdef DEBUG
          //瞬時電力[W] :
          Serial.print("瞬時電力[W] : ");
          Serial.println(rcvdata[53] << 8 * 3 | rcvdata[54] << 8 * 2 | rcvdata[55] << 8 * 1 | rcvdata[56]);

          //瞬時電流[A] R相  :
          Serial.print("瞬時電流[A] R相 : ");
          Serial.println( (rcvdata[59] << 8 * 1 | rcvdata[60]) / 10);

          //瞬時電流[A] T相  :
          Serial.print("瞬時電流[A] T相 : ");
          Serial.println( (rcvdata[61] << 8 * 1 | rcvdata[62]) / 10);

          //積算電力計測値[kW] :
          Serial.print("計測日時:   ");

          Serial.println( rcvdata[65] << 8 * 1 | rcvdata[66]);
          Serial.print("年 ");
          Serial.print( rcvdata[67] );
          Serial.print("月 ");
          Serial.print(  rcvdata[68]);
          Serial.print("日    ");
          Serial.print(  rcvdata[69] );
          Serial.print("時 ");
          Serial.print(  rcvdata[70]);
          Serial.println("分");

          Serial.print("積算電力計測値[kW] : ");
          Serial.println((rcvdata[71] << 8 * 4 | rcvdata[72] << 8 * 3 | rcvdata[73] << 8 * 2 | rcvdata[74] << 8 * 1 | rcvdata[75]) * 10);
#endif


          //変数定義確認用としてメモ
          //float Watt =0 ; //瞬時電力値 [W]
          //float Watt_th = 600; // 瞬時電力値からEV充電可否判断のための閾値 [W]

          Watt = float(rcvdata[53] << 8 * 3 | rcvdata[54] << 8 * 2 | rcvdata[55] << 8 * 1 | rcvdata[56]);
          Serial.println(Watt, 1);//シリアルプロッタ用に瞬時値のみをアウトプット

          if (Watt < Watt_th ) {  //瞬時電力値が判定値を超えた場合にサーボを動かして充電プラグを外す

            start_time = millis();
            while (start_time + change_time > millis()) {
              s_servo.write(map(millis(), start_time, start_time + change_time, 80, 170)); //0度から90度までchange_time[ms]かけて遷移させる。
            }
          } else {
            start_time = millis();
            while (start_time + change_time > millis()) {
              s_servo.write(map(millis(), start_time, start_time + change_time, 170, 80)); //0度から90度までchange_time[ms]かけて遷移させる。
            }
          }

          //
        } else {
          //何もしない
        }



        break;



      case (RES_UDPSEND):
        if (rcvdata[12] == 0x01) {
#ifdef DEBUG
          Serial.println("UDP send 送信 成功");
#endif

        } else {
          Serial.println("UDP send 送信 失敗");
          return FALSE;
        }
        break;

      case (0x2FFF):
        Serial.println("checksum error");
        return FALSE;
        break;
      default:
        Serial.println("uni code error");
        return FALSE;
        break;
    }

  } else {
    Serial.println("recv data error");
    return FALSE;
  }

  return TRUE;
}



/********************************************************************************
    Name     : cmd_send
    Function : REQUEST command to bp35c0-j11
    input    : cmd  - REQUEST command
    return   : TRUE/FALSE
*********************************************************************************/
boolean BP35C0J11::cmd_send(unsigned short cmd) {
  unsigned short hdr_chksum = uni_req[0] + uni_req[1] + uni_req[2] + uni_req[3] ;
  unsigned short dat_chksum = 0 ;
  unsigned short msg_length = 0 ;
  unsigned short dat_length = 0 ;
  unsigned short send_dat_size = 0 ;
  unsigned char data[128] = {0};

  unsigned char send_data[128] = {0} ;
  unsigned char cnt = 0 ;

  switch (cmd) {
    case (CMD_RESET):
      dat_length = 0;
      msg_length = (unsigned short)(4 + dat_length);
      hdr_chksum += CMD_RESET + msg_length;
      dat_chksum = 0 ;
      msg_create(CMD_RESET , msg_length , hdr_chksum , dat_chksum, data , send_data );
      Serial2.write(send_data, (msg_length + CMD_HDR_LEN));
#ifdef DEBUG
      debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif
      //  Serial.println("DEBUG 1-1");

      break;
    case (CMD_INI):
      dat_length = (unsigned short)4;
      msg_length = (unsigned short )( 4 + dat_length);
      hdr_chksum += CMD_INI + msg_length ;
      for (cnt = 0 ; cnt < dat_length ; cnt++ ) {
        data[cnt] = ini_data[cnt] ;
      }
      for (cnt = 0 ; cnt < dat_length ; cnt++) {
        dat_chksum += data[cnt];
      }
      msg_create(CMD_INI , msg_length , hdr_chksum , dat_chksum, data , send_data );
      Serial2.write(send_data, (msg_length + CMD_HDR_LEN));
#ifdef DEBUG
      debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif
      break;


    case (CMD_INI2): //スキャン完了後のBルート動作開始
      dat_length = (unsigned short)4;
      msg_length = (unsigned short )( 4 + dat_length);
      hdr_chksum += CMD_INI + msg_length ;
      for (cnt = 0 ; cnt < dat_length ; cnt++ ) {
        data[cnt] = ini_data[cnt] ;
        if (cnt == 2) {
          data[cnt] = scan_ch[0] ; //アクティブスキャンの際に応答のあったチャンネルを設定する
        }
      }
      for (cnt = 0 ; cnt < dat_length ; cnt++) {
        dat_chksum += data[cnt];
      }
      msg_create(CMD_INI , msg_length , hdr_chksum , dat_chksum, data , send_data );
      Serial2.write(send_data, (msg_length + CMD_HDR_LEN));
#ifdef DEBUG
      debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif
      break;




    case (CMD_B_ROOT_ACTIVE): //Bルート動作開始処理
      dat_length = (unsigned short)0 ;
      msg_length = (unsigned short)(4 + dat_length);
      hdr_chksum += CMD_B_ROOT_ACTIVE + msg_length;

      msg_create(CMD_B_ROOT_ACTIVE , msg_length , hdr_chksum , dat_chksum, data , send_data );
      Serial2.write(send_data, (msg_length + CMD_HDR_LEN));
#ifdef DEBUG
      debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif
      break;



    case (CMD_B_ROOT_PANA): //PANA認証開始要求
      dat_length = (unsigned short)0 ;
      msg_length = (unsigned short)(4 + dat_length);
      hdr_chksum += CMD_B_ROOT_PANA + msg_length;

      msg_create(CMD_B_ROOT_PANA , msg_length , hdr_chksum , dat_chksum, data , send_data );
      Serial2.write(send_data, (msg_length + CMD_HDR_LEN));
#ifdef DEBUG
      debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif
      break;


    case (CMD_PANA_SET):
      dat_length = (unsigned short)16 ;
      msg_length = (unsigned short)(4 + dat_length);
      hdr_chksum += CMD_PANA_SET + msg_length;
      for (cnt = 0 ; cnt < dat_length ; cnt++ ) {
        data[cnt] = password[cnt] ;
      }
      for (cnt = 0 ; cnt < dat_length ; cnt++) {
        dat_chksum += data[cnt];
      }
      msg_create(CMD_PANA_SET , msg_length , hdr_chksum , dat_chksum, data , send_data );
      Serial2.write(send_data, (msg_length + CMD_HDR_LEN));
#ifdef DEBUG
      debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif
      break;


    //Bルート認証設定のコマンド列生成を追加 ここから
    case (CMD_B_ROOT_INI):

      dat_length = (unsigned short)(32 + 12) ;
      msg_length = (unsigned short)(4 + dat_length);
      hdr_chksum += CMD_B_ROOT_INI + msg_length;
      for (cnt = 0 ; cnt < dat_length ; cnt++ ) {
        if (cnt < 32) {
          data[cnt] = b_root_id[cnt] ;
        } else {
          data[cnt] = password[cnt - 32] ;
        }
      }

      for (cnt = 0 ; cnt < dat_length ; cnt++) {
        dat_chksum += data[cnt];
      }
      msg_create(CMD_B_ROOT_INI , msg_length , hdr_chksum , dat_chksum, data , send_data );
      Serial2.write(send_data, (msg_length + CMD_HDR_LEN));

#ifdef DEBUG
      debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif
      break;

    //Bルート認証設定のコマンド列生成を追加 ここまで


    //Bルートのアクティブスキャンを実施 ここから
    case (CMD_SCAN):
      dat_length = (unsigned short)14 ;
      msg_length = (unsigned short)(4 + dat_length);
      hdr_chksum += CMD_SCAN + msg_length;

      for (cnt = 0 ; cnt < dat_length ; cnt++ ) {
        if ( cnt < 6) {
          data[cnt] = scan_CMD[cnt] ;
        } else {
          data[cnt] = b_root_id[cnt - 6 + 24] ;
        }
      }
      for (cnt = 0 ; cnt < dat_length ; cnt++) {
        dat_chksum += data[cnt];
      }
      msg_create(CMD_SCAN , msg_length , hdr_chksum , dat_chksum, data , send_data );
      Serial2.write(send_data, (msg_length + CMD_HDR_LEN));
#ifdef DEBUG
      Serial.print("send=");
      debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif

      //      Serial.println ("Active scanは通過");
      break;

    //Bルートのアクティブスキャンを実施 ここまで


    case (CMD_PORTOPEN):
      dat_length = 2;
      msg_length = (unsigned short)(4 + dat_length);
      hdr_chksum += CMD_PORTOPEN + msg_length;
      for (cnt = 0 ; cnt < dat_length ; cnt++ ) {
        data[cnt] = dist_port[cnt] ;
      }
      for (cnt = 0 ; cnt < dat_length ; cnt++) {
        dat_chksum += data[cnt];
      }
      msg_create(CMD_PORTOPEN , msg_length , hdr_chksum , dat_chksum, data , send_data );
      Serial2.write(send_data, msg_length + CMD_HDR_LEN);
#ifdef DEBUG
      debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif
      break;



    case (CMD_UDPSEND):

      if (state == 8) {
        //■■■スマートメータ―応答値の定義を確認する。■■■
        //動作状態、係数、積算電力量有効桁数、積算電力量単位


        send_dat_size = 20 ; //■下に記載されている送信データサイズと同じ値(DEC)■可変■
        dat_length = 22 + send_dat_size ;
        msg_length = (unsigned short)(4 + dat_length);
        hdr_chksum += CMD_UDPSEND + msg_length;

        for (int i  = 0 ; i < 16 ; i++ ) {//送信先のIPv6アドレス 16byte
          data[i] = IPv6_adr[i] ;
        }
        for (int i  = 16 ; i < 18 ; i++ ) {//送信元のUDPポート番号 2byte
          data[i] = my_port[i - 16] ;
        }
        for (int i  = 18 ; i < 20 ; i++ ) {//送信先のUDPポート番号 2byte
          data[i] = dist_port[i - 18] ;
        }

        //送信データサイズ 2byte 
        data[20] = (unsigned char)(send_dat_size >> 8);
        data[21] = (unsigned char)(send_dat_size & 0xFF); // send data length

        //send_dat_size のByte数として数えるのははここから

        //送信データヘッダ部 10 Byte 
        //ECHONET Lite 電文ヘッダ (2Byte) 基本固定値
        data[22] = 0x10;
        data[23] = 0x81;

        //トランザクションID (2 Byte) 基本固定値
        data[24] = 0x00;
        data[25] = 0x06;

        //送信元オブジェクト (3 Byte) 基本固定値
        data[26] = 0x05;
        data[27] = 0xFF;
        data[28] = 0x01;

        //相手先オブジェクト (3 Byte) 基本固定値
        data[29] = 0x02;
        data[30] = 0x88;
        data[31] = 0x01;

        //各種コマンド送信 10 Byte
        data[32] = 0x62; //サービスコード ESV 0x62=GET
        data[33] = 0x04; //処理プロパティ数 OPC  ■■可変■■  ※EPC+PDCの組み合わせが何回繰り返されるか

        data[34] = 0x80; //ECHONET プロパティ EPC  0x80 : 動作状態
        data[35] = 0x00; //プロパティデータカウンタ PDC

        data[36] = 0xD3; //ECHONET プロパティ 0xD3 :係数
        data[37] = 0x00; //プロパティデータカウンタ PDC

        data[38] = 0xD7; //ECHONET プロパティ EPC  0xD7 : 積算電力量有効桁数
        data[39] = 0x00; //プロパティデータカウンタ PDC

        data[40] = 0xE1; //ECHONET プロパティ 0xE1 :積算電力量単位
        data[41] = 0x00; //プロパティデータカウンタ PDC


        //send_dat_size のByte数として数えるのははここまで


        for (cnt = 0 ; cnt < dat_length ; cnt++) {
          dat_chksum += data[cnt];
        }

        msg_create(CMD_UDPSEND , msg_length , hdr_chksum , dat_chksum, data , send_data );
        Serial2.write(send_data, msg_length + CMD_HDR_LEN);
#ifdef DEBUG
        debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif


      } else if (state == 9) {
        //■■■計測時刻付きで積算電力計測値を取得する(30分ごと更新値)■■■
        //■■■瞬時電力値、瞬時電流値を取得する■■■

        send_dat_size = 20 ; //■下に記載されている送信データサイズと同じ値(DEC)■可変■
        dat_length = 22 + send_dat_size ;
        msg_length = (unsigned short)(4 + dat_length);
        hdr_chksum += CMD_UDPSEND + msg_length;

        for (int i  = 0 ; i < 16 ; i++ ) {//送信先のIPv6アドレス 16byte
          data[i] = IPv6_adr[i] ;
        }
        for (int i  = 16 ; i < 18 ; i++ ) {//送信元のUDPポート番号 2byte
          data[i] = my_port[i - 16] ;
        }
        for (int i  = 18 ; i < 20 ; i++ ) {//送信先のUDPポート番号 2byte
          data[i] = dist_port[i - 18] ;
        }

        //送信データサイズ 2byte 
        data[20] = (unsigned char)(send_dat_size >> 8);
        data[21] = (unsigned char)(send_dat_size & 0xFF); // send data length

        //send_dat_size のByte数として数えるのははここから

        //送信データヘッダ部 10 Byte 
        //ECHONET Lite 電文ヘッダ (2Byte) 基本固定値
        data[22] = 0x10;
        data[23] = 0x81;

        //トランザクションID (2 Byte) 基本固定値
        data[24] = 0x00;
        data[25] = 0x06;

        //送信元オブジェクト (3 Byte) 基本固定値
        data[26] = 0x05;
        data[27] = 0xFF;
        data[28] = 0x01;

        //相手先オブジェクト (3 Byte) 基本固定値
        data[29] = 0x02;
        data[30] = 0x88;
        data[31] = 0x01;

        //各種コマンド送信 10 Byte
        data[32] = 0x62; //サービスコード ESV 0x62=GET
        data[33] = 0x04; //処理プロパティ数 OPC  ■■可変■■  ※EPC+PDCの組み合わせが何回繰り返されるか



        data[34] = 0xE7; //ECHONET プロパティ 0xE7 :瞬時電力計測値
        data[35] = 0x00; //プロパティデータカウンタ PDC

        data[36] = 0xE8; //ECHONET プロパティ 0xE8 :瞬時電流計測値
        data[37] = 0x00; //プロパティデータカウンタ PDC

        data[38] = 0xEA; //ECHONET プロパティ EPC  0xEA : 定時積算電力量計測値 正方向
        data[39] = 0x00; //プロパティデータカウンタ PDC

        data[40] = 0xEB; //ECHONET プロパティ 0xEB :定時積算電力量計測値 逆方向
        data[41] = 0x00; //プロパティデータカウンタ PDC



        //send_dat_size のByte数として数えるのははここまで

        for (cnt = 0 ; cnt < dat_length ; cnt++) {
          dat_chksum += data[cnt];
        }
        msg_create(CMD_UDPSEND , msg_length , hdr_chksum , dat_chksum, data , send_data );
        Serial2.write(send_data, msg_length + CMD_HDR_LEN);
#ifdef DEBUG
        debugmsg( msg_length + CMD_HDR_LEN , send_data);
#endif

      }



      break;

    default:
      break;
  }

  return TRUE;
}

/********************************************************************************
    Name     : msg_create
    Function : create Request command format
    input    : cmd - Request command
               msg_length - message data length
               hdr_chksum - header checksum
               dat_chksum - data checksum
                pdada     - wireless data
                psend_data- request command format data
    return   : -
*********************************************************************************/
void static BP35C0J11::msg_create(unsigned short cmd , unsigned short msg_length , unsigned short hdr_chksum , unsigned short dat_chksum, unsigned char *pdata , unsigned char *psend_data )
{
  unsigned char cnt = 0 ;

  for (cnt = 0 ; cnt < 4 ; cnt++) {
    psend_data[cnt] = uni_req[cnt];
  }
  psend_data[4] = (unsigned char)((cmd & 0xFF00) >> 8);
  psend_data[5] = (unsigned char)(cmd & 0xFF);
  psend_data[6] = (unsigned char)((msg_length & 0xFF00) >> 8);
  psend_data[7] = (unsigned char)(msg_length & 0xFF);
  psend_data[8] = (unsigned char)((hdr_chksum & 0xFF00) >> 8);
  psend_data[9] = (unsigned char)(hdr_chksum & 0xFF);
  psend_data[10] = (unsigned char)((dat_chksum & 0xFF00) >> 8);
  psend_data[11] = (unsigned char)(dat_chksum & 0xFF);

  if (msg_length > 4) {
    for (cnt = 0 ; cnt < msg_length - 4 ; cnt++)
    {
      psend_data[12 + cnt] = pdata[cnt];
    }
  }
}



/********************************************************************************
    Name     : debugmsg
    Function : output serial console for debug
    input    : datalength - output data lengh
               psend_data - output data pointer
    return   : -
*********************************************************************************/
void BP35C0J11::debugmsg(unsigned short datalength , unsigned char* psend_data) {
  unsigned char cnt = 0 ;

  for ( cnt = 0 ; cnt < datalength ; cnt++) {
    Serial.print(psend_data[cnt] , HEX);
    Serial.print(" ");
  }
  Serial.println("");
}

bp35c0-j11.h

/*
  bp35c0-j11.h
 Copyright (c) 2019 ROHM Co.,Ltd.

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
*/


extern unsigned char state;
#include <Servo.h>
static Servo s_servo; /**< Servo object */

#ifndef _BP35C0J11_H_
#define _BP35C0J11_H_

//#define DEBUG



#define CMD_HDR_LEN  ((unsigned char)8)
#define UNI_CODE_LEN ((unsigned char)4)

#define CMD_RESET    (0x00D9)
#define CMD_INI      (0x005F)
#define CMD_HAN      (0x000A)
#define CMD_PANA     (0x003A)
#define CMD_PANA_SET (0x002C)
#define CMD_CON_SET  (0x0025)
#define CMD_UDPSEND  (0x0008)
#define CMD_SCAN     (0x0051)
#define CMD_PORTOPEN (0x0005)

#define NORT_WAKE    (0x6019)
#define RES_INI      (0x205F)
#define RES_HAN      (0x200A)
#define RES_PANA     (0x203A)
#define RES_PANA_SET (0x202C)
#define RES_CON_SET  (0x2025)
#define RES_UDPSEND  (0x2008)
#define RES_SCAN     (0x2051)
#define NORT_SCAN    (0x4051)
#define RES_PORTOPEN (0x2005)
#define NORT_PANA    (0x6028)

#define RES_B_ROOT   (0x2054) // Bルート認証情報設定の応答コマンド
#define RES_B_ROOT_Active     (0x2053) //Bルート動作開始応答
#define RES_B_ROOT_PANA       (0x2056) //PANA認証開始応答
#define RES_COM_STATUS (0x6018)  //接続状態変更通知応答

#define CMD_INI2      (0x1111) // 状態遷移用のダミー

#define CMD_B_ROOT_INI (0x0054) // Bルート認証情報設定
#define CMD_B_ROOT_ACTIVE (0x0053) //Bルート動作開始命令
#define CMD_B_ROOT_PANA (0x0056) // PANA認証開始要求

#define TIMEOUT      ((unsigned short)90000)

#define PIN_ENABLE  (PIN_D20)    // level shifter enable pin
#define PIN_RESET   (PIN_D21)    // wisun module reset pin

#define TRUE 1
#define FALSE 0

typedef struct {
  unsigned char uni_code[4];
  unsigned char cmd_code[2];
  unsigned char msg_len[2];
  unsigned char hdr_chksum[2];
  unsigned char dat_chksum[2];
  unsigned char data[128];
}CMD_FORMAT;

class BP35C0J11
{
	public:
		BP35C0J11(void);
		void j11_init(void);
		boolean wait_msg(void);
		boolean cmd_send(unsigned short cmd);
		void static msg_create(unsigned short cmd , unsigned short msg_length ,unsigned short hdr_chksum , unsigned short dat_chksum, unsigned char *pdata , unsigned char *psend_data );
	private:
		void static debugmsg(unsigned short datalength , unsigned char *psend_data);
};
#endif    //_BP35C0J11_H_
ログインしてコメントを投稿する