エントリー

3.6Vの組充電池用充電器の試作

秋月電子のニッケル水素電池パックは安価で何かと使える3.6V充電池である

IMG_20170903_153320.jpg

これまで(リポを外した)ダイソーのUSB充電ライターの充電機能を利用して充電していた(真ん中のパーツ)

充電は問題なくできるのだがリポ用のため完全な満充電にはならないのが欠点

今後充電する事が増えそうなので専用の充電器を作製しようとしたら実は半年前に作製しようと設計していた(いろいろあって中止し忘れてしまっていたようだ)

diagram.png

ATTINY13aで充電制御する方式で設計,スケッチがまだなのでプログラミングしていたが,今のところ先日の充電器で十分なため記録だけにしておく(他に完了させないといけない物があるので落ち着いたら組み立てる予定)

暫定仕様
  • 全体の8~9割までは500mAの急速充電
  • 残りの1~2割は50%位で充電
  • 最終充電電圧を10秒間保持できていたら充電完了
  • LEDの点滅具合で充電状態が判るようにする
スケッチ
//
// 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: PWM(FET SW)
// 6:
// 7: ADC(充電池電圧確認)
// 8: Vcc 3.3V
//
#include <avr/io.h>

#define BAUD_RATE 38400
#include <BasicSerial3.h>

#define PIN_ADC 1   //PB2(ADC1)
#define PIN_LED PB3 //LED
#define PIN_OUT PB4 //SerialOut(Debug)
#define PIN_FET PB0 //FET

#define MCHR_VOLT (1400*3) //最大充電終止電圧(mV)
#define LAST_VOLT (1420*3) //充電終止電圧(mV)

static void serOut(const char *str) {
while(*str) TxByte(*str++);
}

//確認用シリアル出力
static void voltOut(int v) {
char bf[8];

itoa(v, bf, 10); //10は十進数
serOut(bf);
serOut("mV\r\n");
}

//電圧(mV)
static int voltRead() {
    ADCSRA = (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(0<<ADIF)|(0<<ADIE)|(0b100);
//ADC#3
    loop_until_bit_is_set(ADCSRA,ADIF); //ADC#4
    long v = (long)ADC; //long v = (long)analogRead(PIN_ADC);
    v *= 5000;                           //基準電圧5V
    v /= 1024;
    return((int)v);
}

void setup() {
    DIDR0 = _BV(PIN_ADC);                              //ADC#1: pinMode(PB2, INPUT);
    ADMUX = (0<<REFS0)|(0<<ADLAR)|PIN_ADC; //ADC#2: analogReference(DEFAULT);
    DDRB = (_BV(PIN_LED)|_BV(PIN_FET)|_BV(PIN_OUT));   //pinMode(PIN_LED, OUTPUT);
                                                       //pinMode(PIN_FET, OUTPUT);
                                                       //pinMode(PIN_OUT, OUTPUT);
    OSCCAL = 91;                           //87 - 96 (91, 92)
}

void loop() {
   int volt;

    serOut("Begin.\r\n");

    //MAX充電
   while((volt = voltRead()) < MCHR_VOLT) {
        voltOut(volt);
        PORTB |= _BV(PIN_LED);                         //digitalWrite(PIN_LED, HIGH);
        PORTB |= _BV(PIN_FET);                         //digitalWrite(PIN_FET, HIGH);
        delay(4000);
        PORTB &= ~_BV(PIN_LED);                        //digitalWrite(PIN_LED, LOW);
        delay(1000);
    }

    //残りを50%充電で完了させる
    int final = 5;
    do {
        voltOut(volt);
        PORTB |= _BV(PIN_LED);                         //digitalWrite(PIN_LED, HIGH);
        PORTB |= _BV(PIN_FET);                         //digitalWrite(PIN_FET, HIGH);
        delay(1000);
    PORTB &= ~_BV(PIN_FET);                        //digitalWrite(PIN_FET, LOW);
    PORTB &= ~_BV(PIN_LED);                        //digitalWrite(PIN_LED, LOW);
        delay(1000);
    if((volt = voltRead()) < LAST_VOLT) final = 5;
    } while(--final != 0);

//終了
serOut("End.\r\n");
PORTB &= ~_BV(PIN_LED);                            //digitalWrite(PIN_LED, LOW);
for(;;);
}
コードサイズ
  • arduinoのライブラリを利用すると1Kbytesを超えた
  • ADCを直接ハードウェア操作することで210bytes減る
  • その他も直接操作で最終的に780bytesになっている
  • 確認用のシリアル出力は削除できる
ADC関係
  • ADC#1: デジタル入力抵抗を無効(消費電流が減る)
  • ADC#2: REFS0=Reference: 0でVCC参照, 1で1.1V内部電圧源,ADLAR=0:右詰め,1:左詰め,下位2bitで00から11までADC0からADC3
  • ADC#3: ADEN=ADC有効,ADSC=ADC開始,ADIE=完了割込許可,下位3bitがクロック指定
  • ADC#4: ADIFビットが1の間はAD変換中

ページ移動

コメント

  • コメントはまだありません。

コメント登録

  • コメントを入力してください。
登録フォーム
名前
メールアドレス
URL
コメント
閲覧制限
投稿キー(スパム対策に、投稿キー を半角で入力してください。)

ユーティリティ

タグクラウド

検索

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

Feed