エントリー

カテゴリー「電子工作」の検索結果は以下のとおりです。

デサルフェータ―3号機(試験)

組み込む前に試験するためブレットボードに展開

各電圧確認

PWM出力しないようにしてバッテリーを接続し12Vと5Vの電圧を確認

IMG_20180706_191600556.jpgIMG_20180706_191614398.jpg

PWMのON電圧(閾値)を確認するため電圧を12.0V~13.0Vまで可変したところ設定12.4でONにならず13.0VでもON/OFFを繰り返す現象が発生

IMG_20180706_195026282.jpg

大きな原因は基準電圧が安定してなかったからでLP2950の出力部をオシロで観ると赤LED点灯で右のように変動していた

5V-LED-OFF.jpg5V-LED-ON.jpg

出力部に47μFのケミコンを取り付け5.014Vで安定させた

IMG_20180706_213030963.jpg

またバッテリー電圧チェックのための分圧抵抗にも誤差があるので,12.0~13.0で分圧電圧を実測し誤差分をADCの結果に調整値として追加(必要なのは一部の電圧範囲なので割合ではなく単に誤差分+10した)

12.6V以上ではON,12.5VはON/OFF,12.4V以下でOFFとなることを確認

PWM出力

PWM出力波形をオシロで観たところ4.7kHzのONタイムが10μsで問題なし

PWM-ON.jpgPWM-ON2.jpg

リンギングの確認はとれてないが出力のパルスは出ているようだ

IMG_20180706_215238923.jpgDOUT.jpg

回路図

常時稼働用のスイッチも設け,最終は以下のとおりとなった

パルサー3-1-2_回路図.png

組み込み

ほぼ完成したので組み込むため基板化

IMG_20180707_224927150.jpg

今回はコンパクト化に挑戦し1・2号機のほぼ半分の面積にできた(空き部分はカットする)

動作確認すると1点回路接続ミスがあり燃えるところだった・・・

修正後に再度動作確認してみたところFET,C1(220μF),L1(47μH)の発熱が大きいことが発覚

車載時充電状態となる給電約14.5VだとL1が90℃を超えてしまった

ブレッドボード上では問題なかったので接触抵抗などにより状態が異なるのだろうと思われる

IMG_20180707_234219709.jpg

流石にこれではまずいので対策する

単に熱対策の冷却では根本的解決にならないのでONタイムを調整することにしオシロでデータを取得

IMG_20180708_104903547.jpg

最終的にONタイム10μsだったのを5μsにすることで解決

出力電圧は若干下がったがリンギング波形は綺麗になったようだ

10μs(改善前) 5μs(改善後)
t10us-14.3v-0.jpg t05us-14.3v-0.jpg
before-10us.jpg after-05us.jpg
t10us-14.3v-2.jpg t05us-14.3v-2.jpg

 

ダイソーUSB扇風機

実験で発熱したパーツ等を冷やすため小さな扇風機があれば良いなと思っていたところ,シーズンということもあってかダイソーで扇風機コーナーがあったので見た目使えそうなUSB扇風機を購入してみた

IMG_20180704_192846718.jpg

コンパクト扇風機は前々からダイソーで売っていたみたいで18650を電源にできるタイプもあったようだ(拙者は観たことないけど)

現在では4種類だったけど扇風機コーナーができるくらいなので驚きだ

購入した機種はメタルフレームタイプと記載されており出してみるとフレームは金属性で丈夫そうである

IMG_20180704_192930141.jpg

袋に入っているのはゴム足で土台のフレームに付けて設置を安定させる

IMG_20180704_193023764.jpg

裏には電源スイッチも付いている

IMG_20180705_215020994.jpg

早速ダイソーのUSBバッテリーで動作させてみると,なかなの風力で十分に使えそうなので安心した

IMG_20180704_193333880.jpg

ところが上の回っている羽を見てもらうと判るとおり中心が右下にずれている

このあたりが300円製品といったところなのかな

 

(追加)

IMG_20180705_214801355.jpg

消費電力は電流が227mAだったので約1Wである

デサルフェータ―3号機(スケッチ)

パーツの選択も終えたので制御用のスケッチをプログラミング

主な仕様
  • デサルフェータを実行する最低電圧を設けPWMをON/OFFする(75%以上で実行,充電中は当然ながらONになる)
  • LEDを点灯点滅させて実行中か未実行か判別できるようにする(実行:2秒点灯-1秒消灯,未実行:1秒点灯ー8秒消灯)
  • 異常発生時Attiny13aをリセットする(WDT使用)
  • 約3日毎に再起動(リセット)する
機能の実装方法

①PWM出力

ハードウェアのPWM制御を利用して4000HzのDuty4.8%の12μsを出力だが,メインクロック9.6MHzのままで使いたかったので8分周の4700Hz(=9.6MHz/8/256)でDutyを調整することにした
メインとなる部分だし調整しておかないと次に進めないので,先ずはPWM出力のスケッチを組み実動テストを行い設定値を求め,発熱を抑えたためONタイムが8~9μsになる位のDuty値となった
本テストの際PB0でPWM制御(Dutyを変更しても変化しない)が行えないことが判りPB1を利用するよう回路を変更した

②インターバルタイマー

ATtiny13aはタイマー0しか持っていないためPWMで使用するとarduino環境のタイマーに関連する機能(例えばdelay関数)は使えなくなる
LEDの点滅を行いたいのでPWMのオーバーフロー割込みでカウントして秒単位のwait関数を用意した
オーバーフロー割込みだが,ISR(TIMER0_OVF_vect)で割込みしなくてかなり嵌った
ISR(TIM0_OVF_vect)がATtiny13aの正しいオーバーフロー割込みである

③WDT

システム異常が発生(特に熱暴走)することが想定されるため監視は必須
WDTのリセットはタイマー(実装はPWM割込みの積算で定期的にリセット)で行うことを考えていたが必要ない場合にPWM出力を止められなくなるため,WDTの割込みandリセット手順の割込みでリセットをリジェクトする方法で実装した(お勧めできない方法と説明書にはあるようだ)

④スリープ

省電力モードが必要な訳ではなくループさせて待つは寂しいプログラミングなのでスリープさせることにした
原因が判らないのだが,asm volatile ("sleep")ではスリープしないでのでsleep_mode()を使用(コードはさほど増えないので問題にはならなかった)

⑤ADC

バッテリー電圧のチェックにADCを利用
調整しやすいコンパレーターを使ってみる手もあったがまたの機会とした
回路

Desulfator_3-1.png

  • FUSEを追加
  • L3があるのでL2の位置を変えた
  • PB0(PWM0)ではPWMのDutyが制御できないのでPB1(PWM1)に変更
  • FETのゲートを不定にさせないためR5を追加
  • PB0,PB4を使用して動作させるバッテリ電圧を設定可能にできる(今回は未実装)
スケッチ
// デサルフェータ―3号機
//
// ATMEL ATTINY13 / ARDUINO
//
//                 +-\/-+
// ADC0 (D 5) PB5 1|    |8 Vcc
// ADC3 (D 3) PB3 2|    |7 PB2 (D 2) ADC1
// ADC2 (D 4) PB4 3|    |6 PB1 (D 1) PWM1
// GND            4|    |5 PB0 (D 0) PWM0
//                 +----+
//
// 1: Reset
// 2: LED
// 3: Serial Out
// 4: GND
// 5: SW (常時ピン)
// 6: PWM
// 7: ADC(バッテリー電圧確認)
// 8: Vcc 5.0V
//
// システムクロック:9.6MHz
// PWM周波数:4.7KHz(8分周)
//
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

//#define DEBUG     1

#ifdef DEBUG
#define BAUD_RATE 38400
#include <BasicSerial3.h>
#endif

#ifdef DEBUG
static void serOut(const char *str) {
   while(*str) TxByte(*str++);
}
//番号シリアル出力
static void numberOut(int v) {
    char bf[8];
   itoa(v, bf, 10);                //10は十進数
   serOut(bf);
}
static void newLine() {
    serOut("\r\n");
}
//確認用シリアル出力
static void voltOut(int v) {
    numberOut(v);
    serOut("mV\r\n");
}
#endif

//ピンアサイン
#define PIN_PWM     PB1            //PWM出力(注意:PB0だと指定通りのバルス幅が出ない)
#define PIN_ADC     1               //PB2(ADC1)電圧チェック
#define PIN_LED     PB3             //動作LED
#define PIN_SW      PB0             //常時実行スイッチ
#ifdef DEBUG
#define PIN_SER     PB4             //SerialOut(Debug)
#endif

//PWM利用のための定義
#define PWM_STOP    (B11111000)     //PWM停止(分周ビットマスクとしても利用)
#define PWM_START   ((0<<CS02)|(1<<CS01)|(0<<CS00)) //8分周

// 1 / (9.6MHz / 8分周 / 256) = 1 / 4687.5 = 0.000213 =(周期)
#define CNT_PSEC (4687)             //カウント数/秒
// 12us / 213us * 256 = 14
// 10us / 213us * 256 = 12
//  9us : 10.8 , 8us : 9.6
//#define CNT_DUTY    (10)          //8.32us = (10) * 213us / 256
#define CNT_DUTY    (6)             //5.00us = (6) * 213us / 256
//#define CNT_DUTY (5) //4.16us = (5) * 213us / 256

//スリープ定義
#define SLP_MODE    SLEEP_MODE_ADC
#define sleep()     sleep_mode()    //asm volatile ("sleep")

//WDT利用のための定義
#define WDT_reset() asm volatile ("wdr") //カウンタリセット
#define WDT_500MS   (B000101)
#define WDT_1S      (B000110)
#define WDT_2S      (B000111)
#define WDT_4S      (B100000)
#define WDT_8S      (B100001)

//デサル動作電圧閾値(mV)
#define BTT_CHRG    (13500)
#define BTT_100P    (12600)
#define BTT_075P    (12400)
#define BTT_050P    (12200)
#define BTT_025P    (12000)
#define BTT_ACTN    BTT_075P

//PWM動作状態定義
#define DF_INIT     0               //初期状態
#define DF_STOP     1 //PWM停止中
#define DF_START    2 //PWM動作中
#define RESET_MAX   (3600/9*24*3)  //約3日間毎にリセット
static unsigned df_mode = DF_INIT;
static unsigned reset_count = 0;

//WDTリセット前に呼び出される割込み
ISR(WDT_vect) {
if(reset_count < RESET_MAX) {
//システムリセットを回避
WDTCR |= _BV(WDE)|_BV(WDTIE);
}
   //reset_countはシステムリセットで初期化させる
}

static unsigned temp_count = 0; //秒換算数
static unsigned long sec_count = 0; //累積秒数

//タイマ0:オーバーフロー
ISR(TIM0_OVF_vect) {
if(++temp_count > CNT_PSEC) {
sec_count++;
temp_count = 0;
}
}
//PWMタイマー使用の時間待ち(秒)
static void wait(int t) {
unsigned tc, ttc;
unsigned long sc, ssc;
cli();
ttc = temp_count;
ssc = sec_count + t;
sei();
do {
cli();
tc = temp_count;
sc = sec_count;
sei();
} while(sc <= ssc && (sc != ssc || tc < ttc));
}

//WDT開始(割り込み後システムリセット動作設定)
static void WDT_set(int wt) {
cli(); //割り込み禁止
WDT_reset(); //ウォッチドッグタイマーリセット
WDTCR |= _BV(WDCE)|_BV(WDE)|_BV(WDTIE);
WDTCR |= wt; //タイマ設定
sei(); //割り込み許可
}

//WDT停止
static void WDT_off() {
cli(); //割り込み禁止
WDT_reset(); //ウォッチドッグタイマーリセット
MCUSR &= ~_BV(WDRF); //MCUSRレジスタのウォッチドッグフラグをクリア
WDTCR |= _BV(WDCE)|_BV(WDE); //WDCEとWDEをセット
WDTCR = 0; //ウォッチドッグ停止
sei(); //割り込み許可
}

//電圧(mV)
static int voltRead() {
ADCSRA = (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(0<<ADIF)|(0<<ADIE)|(0b100);
loop_until_bit_is_set(ADCSRA,ADIF);
long v = (long)ADC;
   v += 10;                        //基準電圧,分圧抵抗調整分
v *= (5000 * 4); //基準電圧5V×3:1の分圧
v /= 1024;
#ifdef DEBUG
voltOut(v);
#endif
return((int)v);
}

void setup() {
WDT_off(); //起動直後WDT停止
WDT_set(WDT_8S); //ウォッチドッグタイマ8秒で開始
#ifdef DEBUG
OSCCAL = 91; //87 - 96 (91, 92)
DDRB = _BV(PIN_SER); //pinMode(PIN_SER, OUTPUT);
#endif
//pinMode(PB2, INPUT); analogReference(DEFAULT);
DIDR0 = _BV(PIN_ADC);
ADMUX = (0<<REFS0)|(0<<ADLAR)|PIN_ADC;

//pinMode(PIN_LED, OUTPUT); pinMode(PIN_PWM, OUTPUT);
DDRB |= _BV(PIN_LED)|_BV(PIN_PWM);
    //pinMode(PIN_SW, INPUT_PULLUP);
    DDRB &= ~_BV(PIN_SW);
    PORTB |= _BV(PIN_SW);

//PWM設定
TCCR0A = (1<<COM0B1)|(1<<WGM01)|(1<<WGM00); //非反転出力, 高速PWM動作
TCCR0B = (0<<WGM02); //高速PWM動作(カウンタTOPは最大値の0xff)
OCR0B = CNT_DUTY; //デューティ比(カウンタTOP前にLOWにするための値)

//タイマー割込み
TIMSK0 |= (1<<TOIE0); //オーバーフロー(PWMのTOPで)割り込みを許可
#ifdef DEBUG
TCCR0B |= PWM_START; //常時PWM開始(8分周)
#endif
//スリープモード設定
set_sleep_mode(SLP_MODE);
}

void loop() {
#ifndef DEBUG
//バッテリー電圧チェック
   if((PINB & _BV(PIN_SW)) && voltRead() < BTT_ACTN) {
//動作電圧より低い場合
if(df_mode != DF_STOP) {
TCCR0B &= PWM_STOP; //PWM停止
df_mode = DF_STOP;
}
WDT_off();
WDT_set(WDT_1S);
PORTB |= _BV(PIN_LED); //digitalWrite(PIN_LED, HIGH);
sleep();
WDT_off();
WDT_set(WDT_8S);
PORTB &= ~_BV(PIN_LED); //digitalWrite(PIN_LED, LOW);
sleep();
//9.5秒
} else {
if(df_mode != DF_START) {
TCCR0B |= PWM_START; //PWM開始(8分周)
df_mode = DF_START;
}
for(int n = 0; n < 3; n++) {
PORTB |= _BV(PIN_LED); //digitalWrite(PIN_LED, HIGH);
wait(2);
PORTB &= ~_BV(PIN_LED); //digitalWrite(PIN_LED, LOW);
wait(1);
}
//9秒
}
#else
voltRead();
wait(2);
#endif
reset_count++;
}

なんとか収まった

最大1024バイトのフラッシュメモリのうち、スケッチが866バイト(84%)を使っています。
最大64バイトのRAMのうち、グローバル変数が10バイト(15%)を使っていて、ローカル変数で54バイト使うことができます。

(2018.7.7 変更)

上記スケッチに反映

  • 基準電圧と分圧抵抗の誤差による調整
  • 常時動作SWを追加
  • ONタイムを調整(DUTY変更)
最大1024バイトのフラッシュメモリのうち、スケッチが892バイト(87%)を使っています。
最大64バイトのRAMのうち、グローバル変数が10バイト(15%)を使っていて、ローカル変数で54バイト使うことができます。
Bugs

上記スケッチには認知の不具合があるので記載しておく

  • loop()でWDTをOFFにしているためWDTでリセットされないタイミングがある

これはLEDで本機の状態が判るようにするのを優先したためで,もしLEDが点灯か消灯状態になったらハングアップ,暴走,ループなどの異常状態である(WDTが有効ならリセットされるので点滅の繰り返し)

なので,WDTをOFFに(WDTの操作は)しないでLEDを単に点灯もしくは消灯にしてsleep()させれば解決する

→ WDTのタイムアウトを2秒程度にしてLEDの点灯消灯を操作すれば同じように点滅させることができる

  この方が良さそうなので良いタイミングで変更しようかと思う(以下のようになる)

void setup() {
    WDT_off(); //起動直後WDT停止
    WDT_set(WDT_2S); //ウォッチドッグタイマ2秒で開始



}

void loop() {



    //バッテリー電圧チェック
   if((PINB & _BV(PIN_SW)) && voltRead() < BTT_ACTN) {
        //動作電圧より低い場合
        if(df_mode != DF_STOP) {
            TCCR0B &= PWM_STOP;     //PWM停止
            df_mode = DF_STOP;
        }
        sleep();                    //最初は2秒以内となるので待ち
        PORTB |= _BV(PIN_LED);      //digitalWrite(PIN_LED, HIGH);
        sleep();                    //2秒間点灯
        PORTB &= ~_BV(PIN_LED);     //digitalWrite(PIN_LED, LOW);
        sleep();
sleep();
sleep();
        //10秒
} else {



}

デサルフェータ―3号機(パーツ調整)

最初に設定したパーツではリンギングのピーク電圧は45V位となり十分なのだが周波数が20MHz位もあり共振周波数(2~6MHz)を大きく超えている

《前回の結果:2SK4021,1N5822,47μH》

D-1N5822-4021-47.jpg

このままでも効果はありそうではあるがCouper氏の記事を無視したくないので手持ちのパーツにて検証し調整を試みる

ダイオードの交換

リンギングはダイオードの逆回復時間(trr)が関係しているのだろうと思われ,Couper氏の回路で使用されているファストリカバリ―ダイオードだとGI826CT(trr=200nsとのこと)で約5MHzとなり辻褄があう

同様のダイオードは手持ちにないので,ある分だけでダイオードを交換して検証した

  Type VRRM(V) IF(A) VF(V) trr(ns) 備考
GI826CT FRD 100 6   200 オリジナル回路,入手困難
31DF2 FRD 200 3   30 代替で主に利用されている
C10T06QH SBD 60 11.1 0.66 不明 使用している人がいた
ER504 FRD 400 5 1.25 35 多く使用されている
1N5822 SBD 40 3 0.525 不明 そこそこ使用されている
以下手持ちの実験用
SB340LS SBD 40 3 0.44 不明  
11EQS03L SBD 30 1 0.45 不明  
SS2040FL SBD 40 2 0.4 不明 表面実装のため今回はパス
1N4007 整流 1000 1 1.1 不明 汎用
1S3 整流 30 1 0.5 不明 1N5817の代用品

FRD: ファストリカバリーダイオード
SBD: ショットキーバリヤーダイオード
trr: リカバリタイム(逆回復時間)

《SB340LS》 《11EQS03L》 《1N4007》 《1S3》
D-SB340LS-4021-47.jpg D-11EQS03L-4021-47.jpg D-1N4007-4021-47.jpg D-1S3-4021-47.jpg

リンギングの形は異なるが周波数は変動しなかった

実験したダイオードの逆回復時間は同じだと思えないのでリンギング周波数には影響が少ないということか

FET・コイルの交換

別のパーツの影響を確認(FETまたはコイル(L1)を交換)

《2SK2232》 《100μH》 《2SK2232,100μH》
D-1N5822-2232-47.jpg D-1N5822-4021-100.jpg

D-1N5822-2232-100.jpg

FETを2SK2232にするとリンギング周波数が約100nsの10MHzに変化した

2SK4021:RDS=80mΩ,Vth=1.5~3.5V,tf=15ns

2SK2232:RDS=36mΩ,Vth=0.8~2.0V,tf=55ns

周波数に関係しそうな仕様としてはtfか?

尚,コイルによるリンギング周波数の影響はなく(充電時間が同じなので)電圧が変動する

最終調整

決定したパーツ

  • なるべく共振周波数(2~6MHz)にしたいのでFETは2SK2232を選択
  • ダイオードは出力結果が同じで扱い易い1N4007に変更
  • コイル(L1)は47μH

これまでFETの動作クロックパルスはONタイムを4μsとし,発熱と消費電力を考慮しながら10kHz~20kHz間で調整する予定であったが,FETを交換したことにより電圧が落ち波形のキレが無くなったので再度ONタイムを調整

ピーク電圧と発熱を監視しながら最終的に4000Hz12μsとした

《10μs》 《12μs》 《15μs》 《1N5822,12μs》
R-1N4007-10us.jpg R-1N4007-12us.jpg R-1N4007-15us.jpg

R-1N5822-12us.jpg

1N4007でも1N5822の場合(最右)と遜色ないリンギングとなっている

ページ移動

ユーティリティ

検索

エントリー検索フォーム
キーワード

新着コメント

過去ログ

Feed