Arduinoでエアコンの1時間タイマーを自作する

ダイソーのランタンBIGをPWM調光仕様に改造する

ダイソーのランタンBIGをPICマイコンとMosfetを使ってPWM調光仕様に改造しました。
(改造は自己責任です)

主な仕様
  • PICマイコン - PIC10F322T-I/OT(米粒マイコンだけどPWMが載ってる)
  • Mosfet - AO3400A(30V 5.7A)
  • TC74AC125P(Mosfetのゲートドライバとして使用)
  • LEDに最大約750mA流す(未改造状態より控えめに)
まずは未改造状態の仕様を調べてみました。
テスターで調べる限り、LEDには930mAが流れています(パッケージにある1000mAはまぁ正しい)
36素子あるので1素子は25.8mAほど。

ちなみに新品のエボルタネオを使用していたので電圧は4.8V出ていました。
電力は1.5W近くもあります。
よくこのランタンの改造情報(充電式化やUSB化など)を調べていると2Ωの抵抗を入れるとの話を聞きますが、そうする場合は必ず最低でも2W級の抵抗を入れましょう。最悪燃えます。


ということで今回の回路図です↓

74AC125の"3-ステートコントロール入力ピンG"と、その他の未使用入力ピンは全てGNDに落とします。
そうしないとめちゃくちゃ動作が不安定になります。

2.2Ωの電流制限抵抗は3W級を使用しました。


PICマイコンのプログラム(設定にMCCを使用しています)↓
// CONFIG
#pragma config FOSC = INTOSC    // Oscillator Selection bits->INTOSC oscillator: CLKIN function disabled
#pragma config BOREN = ON    // Brown-out Reset Enable->Brown-out Reset enabled
#pragma config WDTE = OFF    // Watchdog Timer Enable->WDT disabled
#pragma config PWRTE = OFF    // Power-up Timer Enable bit->PWRT disabled
#pragma config MCLRE = OFF    // MCLR Pin Function Select bit->MCLR pin function is digital input, MCLR internally tied to VDD
#pragma config CP = OFF    // Code Protection bit->Program memory code protection is disabled
#pragma config LVP = OFF    // Low-Voltage Programming Enable->High-voltage on MCLR/VPP must be used for programming
#pragma config LPBOR = ON    // Brown-out Reset Selection bits->BOR enabled
#pragma config BORV = LO    // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected.
#pragma config WRT = OFF    // Flash Memory Self-Write Protection->Write protection off

#define _XTAL_FREQ 4000000
#include <xc.h>

void    __interrupt () isr (void); //割り込みプロトタイプ宣言
unsigned int dutyValue[9] = {5,15,25,35,50,200,350,450,499};    //最大値499
unsigned int level = 0;

void main(void) {
    // LFIOFR 31.25KHz_osc_not_ready; HFIOFS unstable; HFIOFR 16MHz_osc_not_ready; IRCF 4MHz; 
    OSCCON = 0x50;
    // CLKROE disabled; 
    CLKRCON = 0x00;
    // SBOREN disabled; BORFS disabled; BORRDY BOR Circuit is inactive; 
    BORCON = 0x00;
    // WDTPS 1:65536; SWDTEN OFF; 
    WDTCON = 0x16;
    
    //LATx registers
    LATA = 0x00;
    //TRISx registers
    TRISA = 0x04;
    //ANSELx registers
    ANSELA = 0x00;
    //WPUx registers
    WPUA = 0x00;
    OPTION_REGbits.nWPUEN = 1;
    
    // PR2 124; 
    PR2 = 0x7C;

    // TMR2 0; 
    TMR2 = 0x00;

    // Clearing IF flag.
    PIR1bits.TMR2IF = 0;

    // T2CKPS 1:4; TOUTPS 1:1; TMR2ON on; 
    T2CON = 0x05;
    
    // Start the Timer by writing to TMRxON bit
    T2CONbits.TMR2ON = 1;
    
    // Set the PWM to the options selected in the PIC10 / PIC12 / PIC16 / PIC18 MCUs.
    // PWM1POL active_hi; PWM1OE enabled; PWM1EN enabled; 
    PWM1CON = 0xC0;   
    
    // Writing to 8 MSBs of PWM duty cycle in PWMDCH register
    PWM1DCH = (dutyValue[level] & 0x03FC)>>2;
     // Writing to 2 LSBs of PWM duty cycle in PWMDCL register
    PWM1DCL = (dutyValue[level] & 0x0003)<<6;
    
    INTCONbits.INTF = 0; //フラグクリア
    OPTION_REGbits.INTEDG = 0; //立下り検知
    INTCONbits.INTE = 1; //外部INT有効
    INTCONbits.GIE = 1; //グローバルINT有効

    RA1 = 0; //使わないピンをLOWに設定
    RA3 = 0; //同上
    
    while(1){
        //外部割り込みでデューティー比を変更するのでメインプログラム無し
    }
}

void PWM1_LoadDutyValue()//デューティー比変更
 {
     // Writing to 8 MSBs of PWM duty cycle in PWMDCH register
     PWM1DCH = (dutyValue[level] & 0x03FC)>>2;
     
     // Writing to 2 LSBs of PWM duty cycle in PWMDCL register
     PWM1DCL = (dutyValue[level] & 0x0003)<<6;

     if(level == 8){ //最大光度を行き過ぎないための待ち
               __delay_ms(3000);
           }

 }

void    __interrupt () isr (void){  //外部割り込み発生で実行
   INTCONbits.INTF = 0; //INTフラグクリア
   INTCONbits.INTE = 0; //外部INT無効
   INTCONbits.GIE = 0; //グローバルINT無効

   __delay_ms(100); //チャタ対策の待ち

   while(RA2 == 0){ //プルアップしてあるのでボタンを押すとピンはLOW

       __delay_ms(700);
       
       if(level < 8){
           level++;
       }
       else if(level == 8 || level > 8){
           level = 0;
       }

       PWM1_LoadDutyValue(); //デューティー比変更関数へ

   }
   INTCONbits.INTE = 1; //外部INT有効
   INTCONbits.GIE = 1; //グローバルINT有効
}

最大光量

最小光量

PWMの周期は2kHzです。
スイッチングのちらつきも特に感じられません。
とりあえずこのランタンはメインとしては使わず最小光量で保安灯的な感じで使うと思います。
ではでは