トップページ     電子回路のページのトップ

 100円充電器用タイマー

 画像をクリックすると拡大表示されます。
 拡大画像からはブラウザの「←戻る」ボタンで戻ってください。


 製作の理由

 以前、100円充電器は使い物にならないと書きましたが、一つ、用途を思いつきました。
 それは弱った電池を充電する場合です。
 100円充電器は充電電流が少ないので弱った電池にとっては優しいのではないかと思いました。
 過放電等で弱った電池を急速充電すれば、さらにダメージが深くなるのではないでしょうか。
 ただし、100円充電器は自動停止しないので、人間が止めなければなりません。
 せめてタイマーがあったら良いのにと思いましたが充電器の内部に組み込むことは困難です。
 そこで、100円充電器専用のタイマーを作ってみました。
 汎用のタイムスイッチでもあれば作る事は無いのですが、持っていないし、あったとしても意外に使いづらかったりします。
 私は100円充電器を7個購入し、4個は放電器に改造した為、トランスは4個ありました。
 残りの3個のうち2個は、今回のテーマである「いたわり充電器」の為に残し、1個は他の用途に予約が入っています。


 ハードウエア

 回路図をクリックすると拡大表示されます。
 拡大図から本文に戻るにはブラウザの←戻る釦を使用してください。

ハードウエア

 相手が100円充電器ですので、極簡単な回路にしました。
 電源は100円充電器から外したトランスを使った関係で倍電圧整流になっています。
 時間設定はボリュームで分圧した5VをA/D変換しているので、大雑把です。
 0〜約24時間が入力できるようになっています。
 運転、停止、リセットは1個の押し釦で切り換えます。
 電源スイッチは付けてありません。
 タイマー表示灯はスタートで点滅し、タイムアップで連続点灯となり、リセットで消灯して初期状態に戻ります。
 タイムカウント中に釦を押すと初期状態に戻ります。
 100円充電器を差し込むコンセントは2個、取り付けましたが動作は同時です。
 単なるタイマーですので他の用途にも使えますが、リレーの接点が1A2つをパラ接続したもの、ヒューズに1Aを入れてあり、 大した負荷は取れません。

 PIC12F675

 PIC12F675は大部昔に買いだめしておいたものですが、使わない内に12F683が出た為、こちらを使うようになり、 さらに、その後12F1822に移りました。
 その為、12F675を使うのは初めてだったりします。
 12F1822と比較すると、かなり見劣りがしますが、当時は200円位していたと思います。
 機能が少ない分、データシートを見るのは楽ですが、SFRのビットの配置が12F683や12F1822と微妙に違って いて、注意が必要です。

製作した基板

製作した基板

 ソフトウエア

 コンパイラはMikroCを使用しました。
 短いプログラムですので、ソースファイルをアップします。
 利用するのは自由ですが、メンテナンスやアフターフォローは行いません。
 製作された場合の結果は自己責任でお願いします。

/////////////////////////////////////////////
//  100円充電器用タイマー  (100yctim.c) //
//   2013/12/11     PIC12F675              //
//   MikroC Pro for PIC Ver 6.0.0          //
/////////////////////////////////////////////

// PIC12F675 4MHz INTERNAL
// INTOSC GP4 GP5 = IO, WDT ON, PupTimer ON,
// GP3 = MCLR, BROWN_OUT = ON, CODE_PROTECT OFF,
// DATA CODE PROTECT OFF

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;

#define SWITCH GPIO.B5
#define LED GPIO.B4
#define RELAY GPIO.B2

#define READY           0
#define READYtoRUN      1
#define RUN             2
#define RUNtoSTOP       3
#define STOP            4
#define STOPtoREADY     5

volatile uchar state;   //ステート
volatile uint m_tics;   //ミリSカウンタ
volatile uint minutes;  //分カウンタ
volatile uchar in_sw;   //チャッタ取りカウンタ
ulong set_time;         //設定時間

union{                  //A/D変換値格納
    int adw;
    char adb[2];
}addata;

void ad_init(void){     //A/D初期化
    ADCON0 = 0x81;      //右詰、VREF=VDD, CH0,
    ANSEL = 0x11;       //Fosc/8, AN0
}

int ad_conv(void){      //A/D変換(16回の平均)
    int i,buff;
    
    buff = 0;
    for(i = 0; i < 16; i++){
        ADCON0.GO = 1;
        while(ADCON0.GO);
        addata.adb[0] = ADRESL;
        addata.adb[1] = ADRESH;
        buff += addata.adw;
        Delay_ms(2);
    }
    buff = buff >> 4;       //1/16
    return buff;
}

void main(void){
    CMCON = 0x7;            //コンパレータを使わない
    OPTION_REG = 0xcf;      //Pull-up off WDT 1/128
    asm CLRWDT;             //ウオッチドッグクリア
    GPIO = 0;               //全ての出力オフ
    TRISIO = 0x29;          //入出力設定 
    WPU = 0;                //内蔵プルアップをしない
    TMR1H = 0xfc;           //Timer1 初期値
    TMR1L = 0x17;           //(1000カウント)
    T1CON = 1;              //タイマー1設定
    PIE1.TMR1IE = 1;        //Timer1 割り込み可
    INTCON.PEIE = 1;        //周辺割り込み可
    INTCON.GIE = 1;         //全割り込み可
    ad_init();
    state = READY;
    while(1){
        asm CLRWDT;
        switch(state){
            case READY:         //待機
                LED = 0;
                RELAY = 0;
                minutes = 0;
                set_time = (ulong)ad_conv()*60L*24L/1024L;  //MAX 24H(1440分)
                //set_time = (ulong)ad_conv()*24L/1024L;  //MAX 24分(デバッグ)
                if(255 == in_sw) state = READYtoRUN;
                break;
            case READYtoRUN:
                if(in_sw)break;
                state = RUN;
                break;
            case RUN:           //タイムカウント
                RELAY = 1;
                if(minutes > set_time){
                    state = RUNtoSTOP;
                    break;
                }
                if(255 == in_sw){
                    state = STOPtoREADY;
                    break;
                }
                break;
            case RUNtoSTOP:
                state = STOP;
                break;
            case STOP:          //タイムアップ
                LED =1;
                RELAY = 0;
                if(255 == in_sw){
                    state = STOPtoREADY;
                    break;
                }
                break;
            case STOPtoREADY:
                if(in_sw)break;
                state = READY;
                break;
        }
    }
}

void interrupt(){               //1mS割り込み
    PIR1.TMR1IF = 0;            //割り込みフラグクリア
    TMR1H = 0xfc;               //Timer1 初期値
    TMR1L = 0x17;               //(1000カウント)
    if(state == RUN) m_tics ++;
    if(m_tics > 59999){
        minutes ++;
        m_tics = 0;
    }
    if(state == RUN){
        if(0 == m_tics%500) LED = ~LED;     //LED点滅
    }
    if(!SWITCH && in_sw < 255) in_sw ++;    //スイッチON確定
    if(SWITCH && in_sw > 0) in_sw --;       //スイッチOFF確定
}

 MikroCは空のプロジェクトが作れません。
 プロジェクトを新規に作成するとプロジェクト名と同じ名前のソースファイルが自動的に作成されてしまいます。
 この中にmain()関数の雛形が作成されています。
 複数のソースファイルを登録する事は出来ますが、main()関数の記述されたソースに例えばmain.cと言った名前を付ける ことが出来ません。
 私は使い易いエディタで予めソースを作成してプロジェクトに追加しています。
 従って自動生成されたソースファイルに作成したファイルを上書きしています。
 今回、最初にビルドしたときmain()関数が定義されていないというエラーが出ました。
 プロジェクトを開いたときソースファイルが表示されていたのでプロジェクトに登録されていると思い込んでいたのですが、 登録されていなかったのです。
 プロジェクトマネージャータブを開き、ソースファイルフォルダを右クリックして登録し、ビルドする事が出来ました。
 他のエディタでプログラムを作成したので、あまり気にならなかったのですが、タブの動きが変です。
 これに関しては設定方法があるようで、ネット上で解説しているページを目にしました。


製作したタイマー

タイマー外観 タイマー内部 充電器を装着
タイマー外観タイマー内部充電器を装着


トップページ  「電子回路」のトップ