なんでも作っちゃう、かも。

Arduino/Make/フィジカルコンピューティング/電子工作あたりで活動しています。スタバの空きカップを使ったスタバカップアンプなど製作。最近はもっぱらArduinoと3Dプリンタの自作に興味があります。

Arduino電力計 - 回路図とスケッチ

Posted by arms22 on 2011年04月26日 26  0

目次

  1. Arduino電力計 - プロトタイプ
  2. Arduino電力計 - 回路図とスケッチ
  3. Arduino電力計 - サージ対策
  4. Arduino電力計 - Pachubeにデータをアップロードする
  5. Arduino電力計 - ケースに組み込む
  6. Arduino電力計 - 2系統対応の回路図とスケッチ
  7. Arduino電力計 - 分電盤に接続

イントロダクション


前回の続き。今回は回路図とArduinoのスケッチについてちょろっと解説します。まだまだ試作の段階なので回路とスケッチは今後も変わると思います。

2011/4/26
回路図とスケッチを更新しました。回路図にはサージ対策を追加、スケッチは電力計算精度を向上させました。


回路図


Power meter /w Arduino 回路図 rev3

電圧の検出には電源トランスを使っています。電源トランスはX1-1,X1-2に接続します。電源トランスの出力はR1/R2によって分圧され、Arduinoのアナログ入力端子1番につながります。R1/R2の分圧比は実験的に求めた値です。使用するトランスによってはArduinoの電源電圧を超えてしまう場合があります。Arduinoに接続する前にテスタでAC電圧を測り、Arduinoの電源電圧を超えてないことを確認します。テスタのAC電圧は平均値なのでピークはもっと高い値になります。テスタで計測したAC電圧に1.414(√2)をかけた値が最大電圧(振幅の最大値)になります。

電流センサはX2-1,X2-2に接続します。電流センサの出力には100Ωの負荷を接続し、Arduinoのアナログ入力端子2番に接続します。電流センサの出力電圧は次の式で求められます。
Eo = K * Io * RL / n
Eo : 出力電圧(Vrms)
K : 結合係数
Io : 貫通電流(Arms)
RL : 外付負荷抵抗(Ω)
n : 巻数(ターン)
巻数は電流センサによって異なります。電流センサのデータシートで確認します。結合係数は負荷抵抗によって変化するので、データシートで確認します。

電源トランス、電流センサの端子X1-2、X2-1にはArduinoの電源電圧を2分の1にした電圧(=VCC/2)を加えます。こうすることで電源トランス、電流センサの出力波形はVCC/2を基準に出力されます。


部品


使用したトランスは大阪高波のSIA-0035という入力100V-出力6V/0.35Aのトランスです。あとになって知ったのですが電圧検出には専用のトランスを使うほうが良いようです。

興和電子工業株式会社 - 電圧検出用トランス(PT・VT)
http://www.kowa-denshi.com/product/trans/PT.html

共立エレショップ - 電源用トランス
http://eleshop.jp/shop/goods/search.aspx

電流センサはU_RDのCTL-6-S32-8F-CLです。共立エレショップで\1,575と少々高めですが、分電盤のワイヤにカチっと挟んで止めるだけで使えます。

共立エレショップ - 分割・クランプ型交流電流センサ / CTL-6-S32-8F-CL
http://eleshop.jp/shop/g/g842136/


スケッチ


// 端子定義
const int arefPin = 0;
const int voltagePin = 1;
const int currentPin = 2;

// 商用電源周波数
#define POWER_FREQ        (60)

// 1サイクルあたりのサンプル数
#define NUMBER_OF_SAMPLES (25)

// サンプリング間隔(マイクロ秒)
#define SAMPLING_PERIOD   (1000000/(POWER_FREQ * NUMBER_OF_SAMPLES))

// デバッグ用
#define DEBUG 1

// 実効電圧、実効電流、有効電力
float Vrms;
float Irms;
float Watt;

// サンプリング用バッファ
int VASamples[NUMBER_OF_SAMPLES*4];

void calcWatt(void)
{
#define kVT    (86.9817579)    // 実測にもとづく係数
#define kCT    (100.0 * 0.99 / 800.0) // R * 係数 / 巻き数

  unsigned long t1,t2;
  int i,r,v1,a1,a2,v2;

  t1 = micros();

  // 1サイクル分のAD値をサンプリング
  for(i=0; i<NUMBER_OF_SAMPLES; i++){

    r = analogRead(arefPin);
    v1 = analogRead(voltagePin);
    a1 = analogRead(currentPin);
    a2 = analogRead(currentPin);
    v2 = analogRead(voltagePin);

    VASamples[(i*4)+0] = v1 - r;
    VASamples[(i*4)+1] = a1 - r;
    VASamples[(i*4)+2] = a2 - r;
    VASamples[(i*4)+3] = v2 - r;

    do {
      t2 = micros();
    } 
    while((t2 - t1) < SAMPLING_PERIOD);
    t1 += SAMPLING_PERIOD;
  }

  // 1サイクル分の電圧と電流、電力を加算
  Vrms = 0;
  Irms = 0;
  Watt = 0;

  for(i=0; i<NUMBER_OF_SAMPLES; i++){
    v1 = VASamples[(i*4)+0];
    a1 = VASamples[(i*4)+1];
    a2 = VASamples[(i*4)+2];
    v2 = VASamples[(i*4)+3];

    float vv = ((((v1+v2)/2) * 5.0) / 1024) * kVT;
    float aa = ((((a1+a2)/2) * 5.0) / 1024) / kCT;

    Vrms += vv * vv;
    Irms += aa * aa;
    Watt += vv * aa;
  }

  // 2乗平均平方根(rms)を求める
  Vrms = sqrt(Vrms / NUMBER_OF_SAMPLES);
  Irms = sqrt(Irms / NUMBER_OF_SAMPLES);

  // 平均電力を求める
  Watt = Watt / NUMBER_OF_SAMPLES;
}

float watt_hour;
float vrms_sum;
float irms_sum;
float watt_sum;
int watt_samples;
unsigned long last_update;

void setup()
{
  Serial.begin(57600);
  watt_hour     = 0;
  vrms_sum      = 0;
  irms_sum      = 0;
  watt_sum      = 0;
  watt_samples  = 0;
  last_update   = millis();
}

void loop()
{
  unsigned long curr_time;

  // 電力を計算
  calcWatt();

  // 1秒分加算する
  vrms_sum += Vrms;
  irms_sum += Irms;
  watt_sum += Watt;
  watt_samples++;

  // 1秒経過したらシリアルに出力
  curr_time = millis();
  if( (curr_time - last_update) > 1000 ){
#if DEBUG
    for(int i=0; i<NUMBER_OF_SAMPLES; i++){
      Serial.print(VASamples[(i*4)+0]);
      Serial.print('\t');
      Serial.println(VASamples[(i*4)+1]);
      Serial.print(VASamples[(i*4)+3]);
      Serial.print('\t');
      Serial.println(VASamples[(i*4)+2]);
    }
#endif
    vrms_sum /= watt_samples;
    irms_sum /= watt_samples;
    watt_sum /= watt_samples;

    Serial.print(vrms_sum);
    Serial.print("Vrms, ");

    Serial.print(irms_sum);
    Serial.print("Irms, ");

    Serial.print(vrms_sum * irms_sum);
    Serial.print("VA, ");

    Serial.print(watt_sum);
    Serial.print("W, ");

    // 力率 = 有効電力 / 皮相電力
    Serial.print((watt_sum * 100) / (vrms_sum * irms_sum));
    Serial.print("%, ");

    // 積算Whを求める
    watt_hour += watt_sum / 3600.0;
    Serial.print(watt_hour);
    Serial.println("Wh");

    watt_samples = 0;
    vrms_sum = irms_sum = watt_sum = 0;

    last_update = curr_time;
  }
}

簡単に処理の流れを解説します。まずsetupでいくつかの変数を初期化、loopで1秒間に数十回calcWattをコール、1秒間の電力の平均を求め、シリアルで出力します。

電圧・電流のサンプリング、電力の計算はcalcWattで行います。calcWattは交流電源の1サイクル分(関西だと60Hz、関東だと50Hz)の電圧・電流をサンプリングし、サンプリングした値から1サイクル分の電圧・電流、電力を計算しています。計算した値はVrms変数、Arms変数、Watt変数に格納します。

電圧はanalogReadで読み取った値をVに変換し、実験で求めた係数(87.5734677)を掛けて求めます。電流は次の式で求められます。
Io = Eo / (K * RL / n)
例えばanalogReadで読み取った値が200mVだった場合、
Io = Eo / (K * RL / n)
Io = 0.2 / (0.99 * 100 / 800)
Io = 0.2 / (0.12375)
Io = 1.6A
となります。

次回はPachubeへのデータアップロードに挑戦します。


Sanwa クランプメータ DCM-400
三和電気計器
売り上げランキング: 510


マザーツール 交流デジタルクランプメータ MT-600A
マザーツール
売り上げランキング: 4903

Ads by Google

26 Comments

yingshu says..."電圧の係数"
 初めまして。

 Arduinoを使って、いろいろ測定をしていますので、
いろいろと参考にさせてもらっています。

 さて、現在は、家の中の消費電力を測定したいと思って、
電流センサなどを購入したところです。
 
 この電圧の係数を求めるための実験はどのようにしたらいいのでしょうか?
 電圧検出用トランスを購入して試してみようと思っていますが、
係数をどのように算出したらいいのか分かりません。

 よろしくお願いします。
2011.04.20 12:12 | URL | #2RkuB7ww [edit]
arms22 says..."Re: 電圧の係数"
電源トランスの1次側の電圧をテスタで計測して、
マイコンAD入力側の電圧をテスタで計測し、
その比を係数としています。

電圧検出用のトランスでしたらデータシートに
入力電圧と出力電圧のグラフが載っていると思うので
そのグラフから読み取ればいいとおもいますよ。
2011.04.20 14:20 | URL | #- [edit]
says..."管理人のみ閲覧できます"
このコメントは管理人のみ閲覧できます
2011.04.21 09:56 | | # [edit]
arms22 says..."Re: No title"
トランス式のDCアダプタをばらして内部のトランスから線だしするのが一番簡単だと思います。あらためてトランスを買う必要もありませんし。ただ使ってみると位相がずれまくってぜんぜんだめみたいなことはあるかもしれません。そこはカットアンドトライで。



電圧検出用トランス、楽天でも買えないようでした?
http://item.rakuten.co.jp/denshi/45065/
2011.04.21 11:35 | URL | #- [edit]
says..."管理人のみ閲覧できます"
このコメントは管理人のみ閲覧できます
2011.04.21 15:43 | | # [edit]
arms22 says..."Re: No title"
こちらでの実験では力率100%と思われる白熱電球で力率96%となっていました。
いろいろ原因は考えられますが、電源トランスがいちばん怪しそうかなと。
オシロスコープで確認したわけではありませんが、電流センサでも位相はずれるかもしれません。
それでも測定の精度は5%ぐらいに落ち着いているので十分かなと思います。
もう少しがんばってみますけどね。
2011.04.21 23:10 | URL | #- [edit]
says..."分電盤の扱いについて"
はじめまして
私もArduinoを使って電力消費を測定し、エネルギーの見える化を行う実験をしようと考えており、大変参考にさせていただいています。
分電盤の作業には電気工事士の資格が必要とのことですが、今回の実験に置いても電気工事士の資格等は必要になるのでしょうか。よろしければご回答お願いします。
2011.04.22 12:52 | URL | #9moh1.ck [edit]
arms22 says..."Re: 分電盤の扱いについて"
いらないと思いますよ。
コンセントにプラグさしたり、
テーブルタップに電流センサ取り付けるだけですから。
でも、100Vの取り扱いには十分気をつけてください。
作業は必ず電源を切った状態で行うなどしてください。
2011.04.22 15:37 | URL | #- [edit]
says..."管理人のみ閲覧できます"
このコメントは管理人のみ閲覧できます
2011.05.06 14:18 | | # [edit]
arms22 says..."Re: No title"
貴重な情報ありがとうございます!
僕も200V入力のトランス、探して試してみます。
2011.05.07 08:21 | URL | #- [edit]
あやのすけ says..."2.5Vのリップル"
こんにちは。
同じ電力計をつくろうとしています!
さて、100kΩの抵抗で分圧して作っている2.5Vをオシロスコープで
観測すると50mVp-p程度の商用周波数が見えているのですが、
測定に影響しませんか?
試しに5kΩに変えると、商用周波は見えません。

または、オシロスコープがたまたま拾っているだけ??

これから、Arduino と繋いでスケッチを動かしてみます。
2011.08.28 17:18 | URL | #0HIVRDtE [edit]
arms22 says..."Re: 2.5Vのリップル"
おおぉ、、、
それは測定に影響しそうですね。
でもまぁもともとそれほど精度は出せてないと思うので
誤差の範囲内かも。
C1をもう少し大きくしたら抵抗大きくできるかも。
2011.08.28 19:27 | URL | #- [edit]
あやのすけ says..."Re: 2.5Vのリップル"
Arduino に繋げてA0のデータを比べてみましたけど、
影響なさそうなので、100kΩのままにしました。
CTをURDのCTL-16なので巻数比を変えています。

すみません、この部分の
float aa = ((((a1+a2)/2) * 5.0) / 1024) / kCT;

(a1+a2)/2 は、2回A/Dしたものを平均しているのかなと
思うのですが、
*5.0 と
/1024 が何の計算をしているのかが、わかりませんでした。
お手数おかけしますが、教えていただけますか。
2011.08.28 23:00 | URL | #0HIVRDtE [edit]
arms22 says..."Re: Re: 2.5Vのリップル"
A/Dコンバータの出力を電圧換算で何Vか求めています。
A/Dコンバータの出力は10bitなので1024で割っています。
5は電源電圧の5Vです。
2011.08.29 08:23 | URL | #- [edit]
あやのすけ says..."Re: Re: Re: 2.5Vのリップル"
ありがとうございます!
家の配電盤は単相三線式なのでL1とL2に電流センサーを取り付けて
電圧測定はトランスを買っていないので、
プログラムをちょっと変更して、L1とL2の電流を
測るようにしました。
結果うまく測定できているようです。
2011.08.30 01:11 | URL | #0HIVRDtE [edit]
arms22 says..."Re: Re: Re: Re: 2.5Vのリップル"
うちも単相三線式ですよ~。
そういえば単相三線式に対応した回路図とスケッチをまだ公開してなかったな。。
2011.08.30 09:37 | URL | #- [edit]
あやのすけ says..."分解能"
簡単なページを作ってみました。
2011.09.04 11:58 | URL | #0HIVRDtE [edit]
arms22 says..."Re: 分解能"
まとめありがとうございます~

Arduinoをサーバーにして~は作ってないけど、
Pachubeにアップロードするスケッチは作ってあるので、
後ほど公開しますね。
2011.09.05 10:02 | URL | #- [edit]
says..."管理人のみ閲覧できます"
このコメントは管理人のみ閲覧できます
2011.10.30 21:42 | | # [edit]
arms22 says..."Re: 7セグで表示したい"
電力の計測と、7セグのダイナミックドライブを同時、
並行して行う必要があります。
詳しくは書けませんが、7セグのダイナミック点灯を
タイマーを使って実装してみてはどうでしょう。
もしくは7セグのダイナミック点灯を別のArduinoにさせるなど検討してみてください。
2011.10.31 12:31 | URL | #- [edit]
says..."管理人のみ閲覧できます"
このコメントは管理人のみ閲覧できます
2011.11.03 22:57 | | # [edit]
arms22 says..."Re: Re: 7セグで表示したい"
そうですね。7セグを制御する側のArduinoは単純にシリアル(RX)で受信した文字を7セグに表示するだけの機能を持たせればいいと思います。
2011.11.03 23:34 | URL | #- [edit]
says..."管理人のみ閲覧できます"
このコメントは管理人のみ閲覧できます
2011.11.10 21:08 | | # [edit]
arms22 says..."Re: Re: Re: 7セグで表示したい"

> 「0」なら「48」、「1」なら「49」、
> 改行は、「10」として表示されてしまいます。
> 「48」「49」「10」という感じです。

送信側が値ではなく文字コードを送っているためだと思います。
受信側で数字を値に変換するか、送信側で値を送るようにすれば良いと思います。

> また、1ケタずつしか送られてきません。20[w]なら、「2」と「0」という感じです。

それは正しい動作です。
受信側で必要な桁数が溜まるまで待つなど工夫してください。
もしくは受信したら表示する桁をずらすとかでいいんじゃないでしょうか。
2011.11.11 09:47 | URL | #- [edit]
says..."管理人のみ閲覧できます"
このコメントは管理人のみ閲覧できます
2011.11.21 23:35 | | # [edit]
says..."管理人のみ閲覧できます"
このコメントは管理人のみ閲覧できます
2013.11.25 04:51 | | # [edit]

Leave a reply






管理者にだけ表示を許可する

該当の記事は見つかりませんでした。