ママゴトの電子コンロを作りました


娘と連れ添いが孫のためにままごと用の調理台を作っていた処に口を挟んだらコンロを担当する羽目になった。
 作るからには最新式の電子コンロがよいのではとなったのでその概要をここにまとめます。
 また、MOSトランジスタによる電源制御、乾電池の電圧を20Vに昇圧するスイッチングレギュレータ、超低費電力マイコンPIC18F24K20とその内部発信器等試して見ようと準備していた物の実験もします。

●ママゴトの調理台と電子コンロの外観

 新聞か雑誌を見たのでしょうか、娘が家でままごとの調理台を作り始めました。
 我が家の方が、材料やネジ、釘、工具が揃っているかららしいのです。それと人手(連れ添い)らしいのです。
 二人は家の中をゴソゴソと捜し回りいろいろな物を集めて作りました。
 水道の蛇口は生ビールサーバーの廃品です、調理台の上のタイルは昔買った物です、骨組みは本棚の残りです。
 私が作った電子コンロは、流しの左側に設置されました。




 私が作った電子コンロです。2口コンロです。
 上の赤い部分が加熱部で赤いLEDを光っているのが見えます。
 手前が操作部で、「電源を入れる」スイッチと各々のコンロの「ON/OFF]「高温」「低温」にするスイッチを配置しています。



●ママゴトの電子コンロの内側

●安全性
 保育園の園児が使うので熱を出す訳にはいかない、そこで光の光具合で発熱加減を表すことにする。
 電源も家庭用のAC100Vを使うのでなく、単3乾電池4個を使い、時間経過で電源オフすることでエコ対応にした。
 そのため、マイコンやオルゴールメロディ用ICは3.3Vで動く低消費品を使い、電源もマイコン制御した。
 加熱温度を表す発光ダイオードは、赤色LEDを8個直列に繋ぎ点灯することにより直列抵抗の無駄な電力消費を軽減する。このため乾電池の電圧をスイッチングレギュレータで20Vに昇圧して使う。


●動き
・電源ON/OFF
 電源ONスイッチ押下で電池から3端子レギュレータで3.3V電圧がマイコンに供給されプログラムが起動すると、電源ONスイッチと並列に接続したMOSトランジスタを導通させ電源を保持する。プログラムで一定時間(1分又は3分)計数してOFFにする。
・コンロ制御
 2ヶのコンロには各々「ON/OFF」「UP」「DOWN」の3つのスイッチがある。
 「ON/OFF」スイッチは、各々のコンロを通電/遮断することと、マイコンに供給する電源の時間を延ばす働きをする。
 「UP」「DOWN」スイッチは、発熱加減を調整する。時間関係は発光周期と発光時間の表の様に、中間温は2秒周期で0.75秒点灯、高温は0.2秒周期で0.1秒点灯、低温は7秒周期で2秒点灯する。
 2個のコンロのどちらかがONならばメロディがなる。


 LEDは天板にスイッチは側板に穴を明けて、乾電池や制御部は底板に取り付けました。
 小基盤は乾電池の電圧を20Vに昇圧するスイッチングレギュレータ、大きい基盤は制御部です。
 制御部の左上は電池から3.3V電圧を作る3端子レギュレータ、その下は左からオルゴールメロディ用IC、電源制御用MOSトランジスタ、全体制御用マイコンで左下はスピーカです。





 スイッチングレギュレータの小基盤と制御部の大きい基盤です。




 制御部の大きい基盤です。マイコンは超低費電力型のPIC18F24K20で内部OSC:8MHzで使っています。




●ママゴトの電子コンロの仕組み

●回路構成
 回路図です。 内部プルアップと8MHzの内部発信器を使った超低費電力マイコンPIC18F24K20を中心に構成したのでシンプルになりました。
 左上は単3電池からの電源をスイッチと並列のMOSトランジスタで制御します。最初は電源スイッチで電源をONするとマイコンが動作してMOSトランジスタを導通させ電源スイッチを離しても電源を確保します。時間が経過すればマイコンはMOSトランジスタをOFFすることで電源を切断します。
 MOSトランジスタを通った電源は3端子レギュレータで3.3Vを作りマイコンに供給することと、スイッチングレギュレータで20Vに昇圧して発光ダイオードを駆動します。赤色LEDを8個直列に繋ぎ点灯することで直列抵抗を少なくすることで直列抵抗による無駄な電力消費を軽減します。色LEDの順方向電圧降下は2V程なので8個直列すると16Vになる。LEDに10mA流すとして100Ωの直列抵抗をつけると電位差1Vとなり17V程の電圧が必要になる。
 オルゴールメロディ用ICは、コンロを加熱している間マイコンで制御しスピーカを鳴らす。オルゴールメロディ用ICは起動すると曲が終わるまで続けるのでLEDが早く消える不具合が有るが笑って済ませるとする。
 LEDやスピーカ、MOSトランジスタの駆動に抵抗内蔵トランジスタを使っている。





●制御概要
 制御のシーケンスです。
 マイコン内蔵の発信器の周波数を内蔵タイマで500Hzに分周してからソフトで50mS等のタイミングを作ります。いろいろな動作は50mSを基本にしています。
 スイッチのチャタリング除去は50mS毎に3回サンプルして判定します。
 丸いスイッチで投入するメイン電源は50mSをカウントして3分/1分を作ります。
 コンロの加熱時間や熱加減は50mSをカウントして表に示すような関係で作ります。





●プログラム
 プルグラムの流れとリストを示します。
 制御のシーケンスを実現します。






// ElecStove

// ???#include <p18f25k20.h>
#include <p18cxxx.h>
// ポート使用状況
//
//緑LED選択 RA2(O)(O)RB7 LED4
//赤LED選択 RA3(O)(O)RB6 LED5
// 7SEG選択 RB0(O)(O)RB5 LED6
// 右ボタン RB1(I)(O)RB4 LED7(右端)

//***** コンフィギュレーションの設定
//CONFIG1H レジスタ
#pragma config OSC = INTIO7 //内蔵オシレータ RA6,RA7=I/Oポートに使用
#pragma config IESO = ON //内蔵オシレータ使用ON
#pragma config FCMEN = OFF //外部クロック異常時のフェイルセーフ監視OFF

//CONFIG2L レジスタ
#pragma config BOREN = ON //ブラウトアウトON
#pragma config BORV = 28 //ブラウンアウト電圧2.7V
#pragma config PWRT = OFF //パワーアップタイマOFF

//CONFIG2H レジスタ
#pragma config WDT = OFF //ウォッチドッグOFF

//CONFIG3H レジスタ
#pragma config MCLRE = ON //MCLR pin enable

//CONFIG4L レジスタ
#pragma config DEBUG = ON //デバッグON
#pragma config LVP = OFF //Single-Supply ICSP OFF
#pragma config STVREN = ON //Stack full/underflow will cause Reset

//CONFIG5L レジスタ
#pragma config CP0 = OFF //コードプロテクションビット OFF
#pragma config CP1 = OFF //コードプロテクションビット OFF
#pragma config CPB = OFF //コードプロテクションビット OFF
#pragma config CPD = OFF //コードプロテクションビット OFF

//CONFIG6L/H レジスタ
#pragma config WRT0 = OFF //ライトプロテクションビット OFF
#pragma config WRT1 = OFF //ライトプロテクションビット OFF
#pragma config WRT2 = OFF //ライトプロテクションビット OFF
#pragma config WRT3 = OFF //ライトプロテクションビット OFF
#pragma config WRTB = OFF //ライトプロテクションビット OFF
#pragma config WRTC = OFF //ライトプロテクションビット OFF
#pragma config WRTD = OFF //ライトプロテクションビット OFF

//CONFIG7L/H レジスタ
#pragma config EBTR0 = OFF //テーブルライトプロテクションビット OFF
#pragma config EBTR1 = OFF //テーブルライトプロテクションビット OFF
#pragma config EBTR2 = OFF //テーブルライトプロテクションビット OFF
#pragma config EBTR3 = OFF //テーブルライトプロテクションビット OFF
#pragma config EBTRB = OFF //テーブルライトプロテクションビット OFF

//// メイン関数
void main(void)
{
#define Tmr50mSValue 50 // Tmr50mSの最大値
#define TmrMainPower1Value 3600 // 3分:TmrMainPower1の最大値
#define TmrMainPower0Value 1200 // 1分:TmrMainPower0の最大値
#define HnHeatTimeValue 600 // 30秒:ヒータnの最大値
#define H1Heat LATAbits.LATA0 //H1Heat
#define H2Heat LATAbits.LATA1 //H2Heat
#define Sound LATAbits.LATA3 //H2Heat

int i, j;
int Tmr50mS, TmrMainPowerValue, TmrMainPower;
int H1TempPeriod, H2TempPeriod, H1HeatTime, H2HeatTime, H1PoinArrTemp, H2PoinArrTemp;
int H1TempTime, H2TempTime;
int ArrTempPeriod[11] = {280,240,200,160,120,80,40,20,12,10,8};
int ArrTempTime[11] = {80,70,60,50,40,30,20,10,6,5,4};

unsigned char uCi, uCj;
unsigned char MainPowerOn;
unsigned char InSwitchData, InSwitch0, InSwitch1, InSwitch2;
// 76543210
OSCCON = 0b01100000; //内蔵オシレータモード:8MHz
TRISA = 0b00000000; //PORTA入出力設定
TRISB = 0b11111111; //PORTB入力設定
TRISC = 0b11111111; //PORTC入力設定
PORTA = 0x00;
INTCON2 = 0b01111111; //Bit7:PORTB入力PullUp設定
ANSEL = 0x00; //ANピンすべてデジタル入出力
ANSELH = 0x00; //ANピンすべてデジタル入出力

TMR2 = 0x00; //タイマー2のカウンタ値
T2CON = 0x1D; //タイマー2:On,PostScale 1/4,PreScale 1/16
PR2 = 250; //タイマー2の比較値 500kHz/250 = 2kHz

LATAbits.LATA4 = 1; //MainPowerロック
if(PORTBbits.RB7) //メインパワースイッチ制御変数の設定?
TmrMainPowerValue = TmrMainPower1Value; //3分:TmrMainPower1の最大値
else
TmrMainPowerValue = TmrMainPower0Value; //1分:TmrMainPower1の最大値

MainPowerOn = 0xFF; // メインパワー変数初期化
InSwitchData = 0x00; // スイッチ入力変数初期化
InSwitch2 = 0x00; // スイッチ入力変数初期化
InSwitch1 = 0x00; // スイッチ入力変数初期化
InSwitch0 = 0x00; // スイッチ入力変数初期化
TmrMainPower = 0x0000; // メインパワースイッチ制御変数初期化
H1TempPeriod = 0x0000; // ヒータ1周期制御変数初期化
H2TempPeriod = 0x0000; // ヒータ2周期制御変数初期化
H1TempTime = 0x0000; // ヒータ1温度制御変数初期化
H2TempTime = 0x0000; // ヒータ2温度制御変数初期化
H1HeatTime = 0x0000; // ヒータ1加熱時間制御変数初期化
H2HeatTime = 0x0000; // ヒータ2加熱時間変数初期化

TmrMainPower = TmrMainPower0Value; //TmrMainPower初期化
Tmr50mS = 0x00; //Tmr50mS初期化
while(1){

// 2mS毎のタイマーONか?
if(PIR1bits.TMR2IF){ //TMR2オーバーフローしたか??
PIR1bits.TMR2IF = 0; //TMR2リセット
Tmr50mS = Tmr50mS + 2; //Tmr50mSを2ms加算

// 50mS経過したか?
if(Tmr50mS >= Tmr50mSValue){ //TMR2がTmr50mSValueを超えたか?
Tmr50mS = 0x00; //Tmr50mS初期化

// H1HeatTime が0ならそのまま 以外ならH1HeatTime を-1
if(H1HeatTime > 0) //Heater1通電中か?
H1HeatTime = H1HeatTime - 1; //H1HeatTime を-1

// H2HeatTime が0ならそのまま 以外ならH2HeatTime を-1
if(H2HeatTime > 0) //Heater2通電中か?
H2HeatTime = H2HeatTime - 1; //H2HeatTime を-1


// スイッチ入力してチャタフリー
InSwitch2 = InSwitch1;
InSwitch1 = InSwitch0;
InSwitch0 = ~PORTB;
InSwitchData = ~InSwitch2;
InSwitchData = InSwitchData & InSwitch1;
InSwitchData = InSwitchData & InSwitch0;

// 50mS毎に TmrMainPower の最大値を経過したかを調べる
TmrMainPower = TmrMainPower - 1; //TmrMainPowerを減らす
if(TmrMainPower == 0){ //メインパワーが最大時間を超えたか?
MainPowerOn = 0x00; //メインパワーリセット
LATAbits.LATA4 = MainPowerOn; //MainPower切断設定
}
}

// 50mS毎の作業
else
{
// 50mS毎に スイッチの押下状態を調べる
if(Tmr50mS == 10){ //Tmr50mS == 10mS か?

// Heater1通電中の スイッチの押下状態を調べる
if(H1HeatTime > 0){ //Heater1通電中か?

// Heater1の加熱UPスイッチの処理
if(InSwitchData & 0x02){ //SwH1UpOn か?
H1PoinArrTemp = H1PoinArrTemp + 1; //H1PoinArrTemp + 1
if(H1PoinArrTemp >= 10) //H1PoinArrTempが最大 か?
H1PoinArrTemp = 10; //H1PoinArrTempの最大を保持
}

// Heater1の加熱Downスイッチの処理
if(InSwitchData & 0x04){ //SwH1DownOn か?
H1PoinArrTemp = H1PoinArrTemp - 1; //H1PoinArrTemp - 1
if(H1PoinArrTemp <= 0) //H1PoinArrTempが最小 か?
H1PoinArrTemp = 0; //H1PoinArrTempの最小を保持
}
} //End Of if(H1HeatTime > 0){ //Heater1通電中か?

// Heater2通電中の スイッチの押下状態を調べる
if(H2HeatTime > 0){ //Heater2通電中か?

// Heater2の加熱UPスイッチの処理
if(InSwitchData & 0x20){ //SwH2UpOn か?
H2PoinArrTemp = H2PoinArrTemp + 1; //H2PoinArrTemp + 1
if(H2PoinArrTemp >= 10) //H2PoinArrTempが最大 か?
H2PoinArrTemp = 10; //H2PoinArrTempの最大を保持
}

// Heater2の加熱Downスイッチの処理
if(InSwitchData & 0x40){ //SwH2DownOn か?
H2PoinArrTemp = H2PoinArrTemp - 1; //H2PoinArrTemp - 1
if(H2PoinArrTemp <= 0) //H2PoinArrTempが最小 か?
H2PoinArrTemp = 0; //H2TPoinArrTempの最小を保持
}
} //End Of if(H2HeatTime > 0){ //Heater2通電中か?


// Heater1 Onスイッチの押下状態を調べる
if(InSwitchData & 0x01){ //SwH1On か?

// H1HeatTime 反転
if(H1HeatTime > 0) //Heater1通電中か?
H1HeatTime = 0; //Heater1をOFFに
else
H1HeatTime = 600; //Heater1を通電中に

// Heater1 Onスイッチの処理
if(H1HeatTime > 0){ //Heater1通電中か?
TmrMainPower = TmrMainPower0Value; //TmrMainPower初期化
H1TempPeriod = 0; //H1TempPeriod 初期化
H1PoinArrTemp = 5; //H1PoinArrTemp初期化
} //End Of if(H1HeatTime > 0){ //Heater1通電中か?
} //End Of if(InSwitchData & 0x01){ //SwH1On か?


// Heater2 Onスイッチの押下状態を調べる
if(InSwitchData & 0x10){ //SwH2On か?

// H2HeatTime 反転
if(H2HeatTime > 0) //Heater2通電中か?
H2HeatTime = 0; //Heater2をOFFに
else
H2HeatTime = 600; //Heater2を通電中に

// Heater2 Onスイッチの処理
if(H2HeatTime > 0){ //Heater2通電中か?
TmrMainPower = TmrMainPower0Value; //TmrMainPower初期化
H2TempPeriod = 0; //H2TempPeriod 初期化
H2PoinArrTemp = 5; //H2PoinArrTemp初期化
} //End Of if(H2HeatTime > 0){ //Heater2通電中か?
} //End Of if(InSwitchData & 0x01){ //SwH1On か?


} //End Of if(Tmr50mS == 10){ //Tmr50mS == 10mS か?


// 50mS毎に2回温度調整の時間経過を調べる
if(Tmr50mS == 20 | Tmr50mS == 46){ //Tmr50mS == 20mS か又は46mS か?

// ヒータ1の加熱時間調整
if(H1HeatTime > 0){ //Heater1通電中か?
H1TempPeriod = H1TempPeriod + 1; //H1TempPeriod + 1
if(H1TempPeriod >= ArrTempPeriod[H1PoinArrTemp]) //H1TempPeriod 1秒以上 か?
H1TempPeriod = 0; //H1TempPeriod 初期化
if(H1TempPeriod >= ArrTempTime[H1PoinArrTemp]) //H1TempPeriodが H1TempTime以上 か?
H1Heat = 1; //H1HeatOn
else
H1Heat = 0; //H1HeatOff
}
else
H1Heat = 0; //H1HeatOff

// ヒータ2の加熱時間調整
if(H2HeatTime > 0){ //Heater2通電中か?
H2TempPeriod = H2TempPeriod + 1; //H2TempPeriod + 1
if(H2TempPeriod >= ArrTempPeriod[H2PoinArrTemp]) //H2TempPeriod 1秒以上 か?
H2TempPeriod = 0; //H2TempPeriod 初期化
if(H2TempPeriod >= ArrTempTime[H2PoinArrTemp]) //H2TempPeriodが H1TempTime以上 か?
H2Heat = 1; //H2HeatOn
else
H2Heat = 0; //H2HeatOff
}
else
H2Heat = 0; //H2HeatOff

Sound = H1Heat | H2Heat; //H2HeatサウンドをON


if((H1HeatTime + H2HeatTime) > 0) //H1か H2が加熱中か?
Sound = 1; //SoundOn
else
Sound = 0; //SoundOff


} //End Of if(Tmr50mS == 20 | Tmr50mS == 46){ //Tmr50mS == 20mS か又は46mS か?
} //End Of else
} //End Of if(PIR1bits.TMR2IF){
} //End Of while(1){
} //End Of void main(void)




ホームへ戻る