目次 |
AC電流測定用の変流器を用いて、PICでAC電流を測る。この測定変流器は抵抗付きのものと、抵抗を自分で用意して取り付けなければならないものがある。日本の電子部品屋で売っているものは抵抗なしの変流器のみが多く、中国の商社から直接輸入する時は抵抗付きのものが多い。
今回はURD社のCTL-6-P-Hという小型変流器を用いた。どのような範囲の電流値でも測定したいため、可変抵抗器を取り付けている。なお、PIC microcontroller用センサー汎用ライブラリには、理想的な正弦波曲線で電流値が振幅する場合のプログラムを掲載したが、実際は次に示すような歪んだ電流波形の場合が多い。
こういう場合の電流値の求め方は、「瞬時の電流値を一定時間足し合わせた平均値」のほうがふさわしい。
BSch3V用回路図ファイルをダウンロードする, PasS用プリント基板ファイルをダウンロードする
4秒毎に電流測定し、シリアル伝送するプログラム
// A/D サンプル数 #define AD_SAMPLE 2500 // データ送信の間の待ち時間(ミリ秒) #define WAIT_MSEC 1510 // ステータスLED発光時間(ミリ秒) #define STATUS_BLINK_MSEC 5 /* printf関数の出力先のスタブ関数を定義する */ void putch(unsigned char ch){ rs232c_putch(ch); return; } void main(void) { // 基本機能の設定 OSCCON = 0b01101010; // 内部オシレーター 4MHz TRISA = 0b00101001; // IOポートRA0(AN0),RA5(RX)を入力モード(RA3は入力専用)、RA1,RA2,RA4(TX)を出力モード APFCONbits.RXDTSEL = 1; // シリアルポート RXをRA5ピンに割付 APFCONbits.TXCKSEL = 1; // シリアルポート TXをRA4ピンに割付 ANSELA = 0b00000001; // A/D変換をAN0を有効 AN1,AN2,AN4を無効 PORTA = 0; ADCON0 = 0; // AN0選択, A/D機能停止 ADCON1 = 0b10010000; // 変換結果右詰, クロックFOSC/8, 比較対象VDD // 1秒待つ __delay_ms(1000); rs232c_init(9); // init 9600bps TRISAbits.TRISA5 = 0; // RA5(RX)は使わないので、消費電力低減のため出力モードにしておく while(1) { unsigned int value_max = 0, value_min = 0xffff; // 検出電流の最大・最小値 float value_sum = 0.0; // 中間計算(合計値) for(unsigned int i = 0; i < AD_SAMPLE; i++){ ADCON0bits.ADON = 1; // A/D機能ON __delay_us(10); // A/D変換器チャージ時間待つ ADCON0bits.GO = 1; // A/D開始 while(ADCON0bits.GO_nDONE){} // A/D変換完了を待つ unsigned int value = ADRESH << 8 | ADRESL; ADCON0 = 0; // AN0選択, A/D機能停止 if(value > 512) value_sum += (value - 512); else value_sum += (512 - value); if(value > value_max) value_max = value; if(value_min > value) value_min = value; __delay_us(10); } // サンプル数で割って平均値を求める。なお、0 - 1024のレンジに調整するため、sin正弦波平均値2/piを考慮し、 // 1024 / (512 * 2/pi) を調整する int value_average = (int)((value_sum / AD_SAMPLE) * (1024 / 325)); // 効率。最大振幅の綺麗なsin波だった場合の平均値2/piで割る(実際は352で割ればよい) int value_efficiency = (int)((value_sum / AD_SAMPLE) / ((value_max - value_min)*0.3185) * 100); // Status LED ON PORTAbits.RA2 = 1; // データ送信 (to Serial) printf("%d,%d,%d,%d\r\n", value_min, value_max, value_average, value_efficiency); __delay_ms(STATUS_BLINK_MSEC); // Status LED OFF PORTAbits.RA2 = 0; // 2秒に1回データ送信する __delay_ms(WAIT_MSEC); } }