きっかけ
昔にAliExpressでPDやQCが使えるモジュールを購入して3Dプリンターでケースを作って使用していたのですが、踏んでケースを壊してしまった時に、もっと立派な充電器を作ろうと思いました。使われているチップ(SW3516)について調べてると、データーシート(ミラー、日本語訳版)曰くi2cが出ているらしく、色々読めるっぽい(値についての資料(ミラー))ので試してみることにしました。
使用機材・事前準備
今回はArduino UNO(の互換機)を使用しました。
使用したモジュール(DC Quick Chage Adapter)にはi2cようのパターンがないため、ハンダで外付けしました。下に記した図のように20ピンがSDA、21ピンがSCKであるためそこにはんだ付けします。
配線は、Arduino UNOのDCL、SDAとGNDをそのまま繋ぐだけです。
Arduinoのプログラム(動作確認)
i2cであっても、レジスタを読まないといけないので、Qiitaを参考にしました。
Qiita-ArduinoのI2C通信でデバイスのレジスタにアクセスする。
これを参考に書いたコードがこちらです
#include <Wire.h>
const int Device_Address = 0x3C; //i2cアドレス
const int Register_Address[] = {0x01,0x06,0x07,0x12,0x13,0x30,0x31,0x32,0x33,0x34,0x35,0x37,0x38,0x3A,0x3B,0x3C,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5};//レジトリアドレス
int Register_Data[22]; //取得したデータを入れる配列
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("end setup");
}
void loop() {
for (int i = 0; i <= 21; i++){ //レジストリの読み取り
//Serial.print("reading...");
//Serial.println(Register_Address[i],HEX);
Wire.beginTransmission(Device_Address); //i2cデバイスのアドレス指定
Wire.write(Register_Address[i]); //アドレスの指定
Wire.endTransmission(false); //request後もコネクションを維持
Wire.requestFrom(Device_Address, 1,true); //出力の指定
Register_Data[i] = Wire.read(); //読み出す
delay(0);
}
for (int i = 0; i <= 21; i++){ //Register_Dataの表示
Serial.print(Register_Address[i],HEX);
Serial.print(" = ");
Serial.println(Register_Data[i],BIN);
}
delay(5000);
}
単純にレジストリを読み込んで、バイナリを出力するだけのプログラムです。レジストリの意味については、これ(ミラー)を参考にしてください。
こんな感じに表示されるとい思います。使用中のプロトコルや、電流が読めると思います。
Arduinoのプログラム(ライブラリの使用)
ここから、みやすいようにするプログラムを書いていたんですが、調べたらArduino向けライブラリがあったので使ってみます。
GitHub-SW35xx Library for Arduino
この後色々エラーが出るので、エラーが出ない改変バージョンのzipを置いておきます。
zipファイルで落としてきて、スケッチ→ライブラリのインクルード→.ZIP形式のライブラリをインストール…で読み込みします。
以下のエラーはh1_SW35xx-custom.zipでは出ないはずです…
SimpleTestっていうサンプルがありますが、コンパイルしてみるとprintfが使えないよっていうエラーが大量に出て、コンパイルできないと思います。もしくは、cstdintがないよか、BITがじゃなくてBINじゃない?みたいなエラーが出ると思います。
とりあえずprintf対策で作り直しました。ディフォルトの設定だと、入力電圧が読み取れないためレジスタの13アドレスを2に変更して読めるようにします。
#include <Arduino.h>
#include <h1_SW35xx.h>
#include <Wire.h>
using namespace h1_SW35xx;
SW35xx sw(Wire);
void setup() {
Serial.begin(9600);
Wire.begin();
//13アドレスを読む
Wire.beginTransmission(0x3C);
Wire.write(0x13);
Wire.endTransmission(false);
Wire.requestFrom(0x3C, 1,true);
Serial.println(Wire.read(),BIN);
//13アドレスに2を書き込み(入力電圧測定の有効化)
Wire.beginTransmission(0x3C);
Wire.write(0x13);
Wire.write(0x2);
Wire.endTransmission(false);
//13アドレスを読む(書き換わったか確認)
Wire.beginTransmission(0x3C);
Wire.write(0x13);
Wire.endTransmission(false);
Wire.requestFrom(0x3C, 1,true);
Serial.println(Wire.read(),BIN);
sw.setMaxCurrent5A(); //5Aの出力をできるようにする
}
const char *fastChargeType2String(SW35xx::fastChargeType_t fastChargeType) {
switch (fastChargeType) {
case SW35xx::NOT_FAST_CHARGE:
return "Not fast charge";
break;
case SW35xx::QC2:
return "QC2.0";
break;
case SW35xx::QC3:
return "QC3.0";
break;
case SW35xx::FCP:
return "FCP";
break;
case SW35xx::SCP:
return "SCP";
break;
case SW35xx::PD_FIX:
return "PD Fix";
break;
case SW35xx::PD_PPS:
return "PD PPS";
break;
case SW35xx::MTKPE1:
return "MTK PE1.1";
break;
case SW35xx::MTKPE2:
return "MTK PE2.0";
break;
case SW35xx::LVDC:
return "LVDC";
break;
case SW35xx::SFCP:
return "SFCP";
break;
case SW35xx::AFC:
return "AFC";
break;
default:
return "unknown";
break;
}
}
void loop() {
sw.readStatus();
Serial.print("Current input voltage:");
Serial.print(sw.vin_mV);
Serial.println("mV");
Serial.print("Current output voltage:");
Serial.print(sw.vout_mV);
Serial.println("mV");
Serial.print("Current USB-C output cuurent:");
Serial.print(sw.iout_usbc_mA);
Serial.println("mA");
Serial.print("Current USB-A output cuurent:");
Serial.print(sw.iout_usba_mA);
Serial.println("mA");
Serial.print("ChageType:");
Serial.println(fastChargeType2String(sw.fastChargeType));
if (sw.fastChargeType == SW35xx::PD_FIX || sw.fastChargeType == SW35xx::PD_PPS){
Serial.print("PDversion:");
Serial.println(sw.PDVersion);
}
delay(2000);
}
これで、コンパイルできればいいんですが、自分はあと、cstdintが見つからないってエラーが出たので他のライブラリからcstdintをコピーしました。詳しくはこの記事を参考にしてください。
Arduinoのライブラリ.hにcstdintが見つからないって言われる時の対処法
これで、このエラーは出なくなったんですが、次は、
In file included from /Users/unagidojyou/MEGA/Arduino/Arduino_SW3516_Library_test/Arduino_SW3516_Library_test.ino:2:0:
/Users/unagidojyou/Documents/Arduino/libraries/h1_SW35xx-master/src/h1_SW35xx.h:30:21: error: 'BIT' was not declared in this scope
QC_CONF_PE = BIT(0),
^~~
/Users/unagidojyou/Documents/Arduino/libraries/h1_SW35xx-master/src/h1_SW35xx.h:30:21: note: suggested alternative: 'BIN'
QC_CONF_PE = BIT(0),
^~~
BIN
みたいな感じで大量のエラーが出るっぽいです。どうやらBITっていう関数が見つからないらしいです。Wikiで調べてみた感じBITではなくbitが正しいっぽいので、/Users/”ユーザー名”/Documents/Arduino/libraries/h1_SW35xx-master/src/h1_SW35xx.hのBITをbitに変えました。
これでやっとコンパイルが通るようになります。こうゆう場合ってGitHubにissueを立てた方がいいのかなぁ
実行結果はこんな感じになります。
PD3で9V出力されているのが確認できます。
終わりに
ライブラリがちょっと曲者でしたが、なかなか面白いですね
LCDや昇圧コンバータと組み合わせて各種電圧、電流を計測できるやつを作ってみます。