
100均のナイトライト、便利だけど電池交換がプチストレスで

1回使うと、廊下のスイッチで電気をつけるのがめんどくさくなるほど便利な、人感センサで光るナイトライト。100均で売っていて、夜中にトイレに行くたびに自動で光ってくれてとても便利なんです。ただ100円じゃなくて300円の商品です。でも300円で実現できるなんてすごいですよね。
でも、また電池切れです。しばらく使っていると、突然光らなくなってしまいます。このライトに頼っているので、使えないとストレスなんです。
ある日ふと思いました。「太陽電池で充電できたら、電池交換不要でずっと使えるんじゃないか?」と。しかも電池を捨てないのでエコです。これは作るしかありません。早速作りましょう!
太陽電池で充電する仕組みを考える
充電電池じゃダメなの?
最初は太陽電池で充電電池を充電する方法を考えていました。ところが、充電電池には寿命があります。だいたい500回充電すると寿命になるので、2年くらいで充電電池の交換が必要になってしまいます。
これでは本末転倒です。電池交換から逃げようとしたのに、また電池交換が必要になるとは…。
そこで調べていると、スーパーキャパシタというものを発見しました。超大容量のコンデンサで、なんと1万回から10万回充放電できるというのです。1万回でも27年で、10万回なら274年です。太陽電池とスーパーキャパシタを組み合わせれば、半永久的に使えるナイトライトが作れそうです。これはいいかもしれませんよ。
太陽電池の落とし穴
ところが、太陽電池には厄介な特性があります。発電しているときは電池のように振る舞うのですが、発電していないとき、つまり夜になると、プラスとマイナスがショートした状態になってしまうんです。

なぜかというと、太陽電池はダイオードと仕組みが同じだからです。発電しないと放電する方向に向かってダイオードがつながっているのと同じなんです。
何が起きるかというと、太陽電池とスーパーキャパシタを直接つなぐと、昼間は充電できるのですが、夜になるとせっかく貯めた電気が太陽電池に逆流して放電されてしまいます。昼間苦労して貯めた電気が、夜中に全部逃げていくわけです。これは困りました。

解決策はダイオードです。太陽電池からスーパーキャパシタの方向にしか電気が流れないようにダイオードを間に入れることで、この逆流を防ぐことができます。
実験してみたら、うまいこといけちゃいました

太陽電池にダイオードを経由してスーパーキャパシタを接続し、窓に貼り付けて充電できるか実験してみました。
明るい曇りの日に朝6時から充電を開始したところ、12時には4.7Vまで充電できました。太陽電池の発電電圧が5Vくらいで、ダイオードのロスが0.3V程度あるので、ちゃんと充電できてますね。これなら実用になりそうです。作戦続行です。
LEDを点灯させて、また問題発生
スーパーキャパシタの困った特性

よし、あとはLEDをつなぐだけ…と思ったら、また問題発生です。

充電電池は放電時の電圧が一定なので、LEDをつないでも電池が空になるまで常に同じ明るさで光ります。ところがスーパーキャパシタは、放電するにつれて徐々に電圧が下がっていきます。
実験してみると、7分くらいで明るさが半分くらいになっていました。満充電のときは明るいのに、時間が経つにつれてどんどん暗くなっていく。明るくなければナイトライトとして使い物になりません。なかなか一筋縄ではいきませんね。
昇降圧DCDCコンバータで解決!
そこで登場するのが昇降圧DCDCコンバータです。0.5Vから5.5Vの範囲の電圧を、一定の電圧に変換してくれる部品です。スーパーキャパシタの電圧が徐々に下がっていっても、昇降圧DCDCコンバータを接続すれば、電圧を一定に保ってくれます。これは使えそうです。

さっそく試してみると、4.7Vまで充電したスーパーキャパシタが0.47Vになるまで、出力電圧が5V一定でLEDの明るさも変わりませんでした。しかも18分も一定の明るさをキープします。昇降圧DCDCコンバータがない場合には7分で半分の明るさだったので、効果絶大です。
やりました、これで明るさ問題は解決です。
ひとつ困ったのは、昇降圧DCDCコンバータICの出力電圧が3.3Vか5Vのものしか見つからなかったことです。LEDは3.3V程度で明るく点灯するのですが、マイコンのIOポートが0.6V程度ロスをするので、電源電圧が3.3VではLEDが明るく光りません。本当は電源電圧は4V程度が丁度いいのですが、ちょっと効率が下がりますがここは仕方なく5Vを選択することとしましょう。
人と明るさに反応して光るようにする
必要な部品を揃える
「暗くなったら人に反応して10秒間だけ光る」という仕組みを作り上げたいのです。このような動作をさせるために、3つの部品を用意します。
明るさセンサ:明るいと電流がたくさん流れて、暗いと電流が少ししか流れない部品です。センサにつないだ抵抗の電圧を読み取ることで、今が明るいのか暗いのかがわかります。
人感センサ:前回のネズミ避けでも活躍したSR602を使います。省電力で動作するので、このような用途にぴったりです。人に反応すると5秒程度ONする信号を出力します。ただしSR602は電源電圧が5Vでも信号の出力電圧は3.3Vなので、5Vで動作するマイコンにつなぐためには、この信号を5Vに変換する必要があるかもです。今回は変換することにしました。
マイコン:明るさセンサのアナログ値を読み取るためにADコンバータが搭載されていて、かつ省電力なものが必要です。PadaukのPFS123はADコンバータも内蔵していて、ローテクな用途を低消費電力で動かすのに最適です。
プログラムの動き
プログラムはシンプルです。
- スリープして人感センサからの信号が来るのを待機
- 人感センサが反応してマイコンを起こす
- 明るさセンサの電圧をAD変換して、暗いかどうかチェック
- 暗かったら10秒間LEDをON
- 1に戻ってスリープ
人がいないときはずっとスリープしているので、消費電力をとことん抑えることができます。
基板を作って組み立てる
とりあえず作ってみる

これらの部品を組み合わせて、とりあえず組み立ててみました。正常に動作しているみたいですよ。ここまで順調です。
JLCPCBに発注

KiCadで設計した基板をJLCPCBに発注しました。小さな基板ならなんと$2(送料は別)で作れてしまうので、失敗してもまた発注すればいいやと思える値段なのがいいですね。

発注して10日くらいで基板が届きました。今回はコスト節約のためメタルマスクは作らず、シリンジに入ったクリームはんだを基板のパッドに塗布して、部品を載せてオーブンでリフローする方法で組み立てました。この方法でも、きれいに仕上がりました。

太陽電池をつなげば、半永久動作のソーラー人感センサナイトライトの完成です。
実際に設置して、夜を待つ

基板は廊下の天井に画鋲でとめました。画鋲なのでいつでも外せて便利です。

太陽電池は窓の近くに貼り付けて、昼間の間にスーパーキャパシタをじっくり充電します。
あとは夜を待つだけです。ドキドキします。充電した電気で光るかな?
夜になって、ライトの近くにそっと近づいてみると…

フワッとLEDが光りました。PWMで滑らかに明るさが変化するようになっているんです。よっし!動いていますよ!
電池交換不要、太陽の光だけで動き続ける、半永久的なソーラー人感センサナイトライトが完成しました!あのプチストレスだった電池交換から、ようやく解放されました。
今回の製作を通して、太陽電池+スーパーキャパシタ+昇降圧DCDCコンバータの組み合わせで、半永久的に使える電源が実現できました。これ、ナイトライト以外にも使えそうですよ。IoT機器など、ワイヤレスで動かしたい機器の電源としても活躍してくれるんじゃないかと思います。私も新しいアイデアが、湧いてきました。なんかワクワクしますね。今回の製作がみなさんのヒントになれば嬉しいです!
付録
プログラム
今回作ったPadauk PFS123のプログラムになります。
#include <pdk/device.h>
#include <stdint.h>
#include "auto_sysclock.h"
#include "startup.h"
#include "delay.h"
#include "ad.h"
#include "serial.h"
#define PWM_OUT 3
#define PWM_MAX 0x3F //MIN Brightness 0x3F
#define PWM_MIN 0 //MAX Brightness
#define AMBIENT_SENSOR_ENABLE_PIN 5
#define AMBIENT_SENSOR_DISABLE() PA |= (1 << AMBIENT_SENSOR_ENABLE_PIN)
#define AMBIENT_SENSOR_ENABLE() PA &= ~(1 << AMBIENT_SENSOR_ENABLE_PIN)
#define DAY_DETECTION_VALUE 0x3000
#define NIGHT_DETECTION_VALUE 0x2E00
#define PIR_PIN 6
#define PIR_STATES() ( PA & (1 << PIR_PIN) ) != 0
#define PIR_ON 0
#define PIR_OFF 1
#define LED_PIN 7
#define LED_ON() PA |= (1 << LED_PIN)
#define LED_OFF() PA &= ~(1 << LED_PIN)
void fadeOut()
{
for( uint8_t pwm = PWM_MIN ; pwm < PWM_MAX ; pwm++)
{
TM2B = pwm;
_delay_ms(10);
}
TM2B = PWM_MAX;
}
void fadeIn()
{
for( uint8_t pwm = PWM_MAX ; pwm > PWM_MIN ; pwm--)
{
TM2B = pwm;
_delay_ms(10);
}
TM2B = PWM_MIN;
}
void main() {
//IO ALL OUTPUT
PA |= (1 << PWM_OUT); //PWM LED OFF
PAC = 0xFF;
PBC = 0xFF;
PCC = 0xFF;
CLKMD &= ~CLKMD_ENABLE_WATCHDOG; // Disable WDT
//Timer2
PA |= (1 << PWM_OUT);
PAC |= ( 1 << PWM_OUT);
TM2B = PWM_MAX;
TM2C = (uint8_t)(TM2C_CLK_ILRC | TM2C_MODE_PWM | TM2C_OUT_PA3);
TM2S = (uint8_t)(TM2S_PWM_RES_6BIT);
ROP = (uint8_t)(ROP_TMX_6BIT);
//for A/D
initADPin( ADPIN_PA4 );
//for PIR
PAC &= ~( 1 << PIR_PIN);
//for INPUT setting
uint8_t pbdierReg = 0;
pbdierReg |= ( 1 << 4 ); //for AD PA4 INPUT
pbdierReg |= ( 1 << PIR_PIN ); //PIR INPUT
PADIER = pbdierReg; //PBDIERはリードできないので一括で設定する必要がある PBDIER can't read. Need to set one time.
PAPH |= ( 1 << PIR_PIN ); //PIR INPUT PULLUP
//for AMBIENT_SENSOR_ENABLE
AMBIENT_SENSOR_DISABLE();
PAC |= ( 1 << AMBIENT_SENSOR_ENABLE_PIN);
//for LED
LED_ON();
PAC |= ( 1 << LED_PIN);
//for Serial
initSerial();
uint16_t dayNightDetectValue = NIGHT_DETECTION_VALUE;
while(1){
LED_ON();
if( PIR_STATES() == PIR_OFF ) //PIRがOFFだったらスリープする
{
__stopsys();
}
//Get ambientsensor vale
uint16_t adValue = 0;
AMBIENT_SENSOR_ENABLE();
for( uint8_t i=0 ; i<16 ; i++){
adValue += getADC( ADPIN_PA4 );
}
AMBIENT_SENSOR_DISABLE();
serial((uint8_t)(0xFF));
serial((uint8_t)(adValue >> 8));
serial((uint8_t)(adValue & 0x00FF ));
serial((uint8_t)(0x00));
if( adValue < dayNightDetectValue ) //暗かったらLEDを点灯させる
{
dayNightDetectValue = DAY_DETECTION_VALUE;
fadeIn();
do{
for( uint8_t i=0 ; i<10 ; i++){
_delay_ms(1000);
}
}while( PIR_STATES() == PIR_ON );
fadeOut();
}else{
dayNightDetectValue = NIGHT_DETECTION_VALUE;
_delay_ms(500);
while( PIR_STATES() == PIR_ON )
{
_delay_ms(1000);
}
}
}
}
// Startup code - Setup/calibrate system clock
unsigned char STARTUP_FUNCTION(void) {
// Initialize the system clock (CLKMD register) with the IHRC, ILRC, or EOSC clock source and correct divider.
// The AUTO_INIT_SYSCLOCK() macro uses F_CPU (defined in the Makefile) to choose the IHRC or ILRC clock source and divider.
// Alternatively, replace this with the more specific PDK_SET_SYSCLOCK(...) macro from pdk/sysclock.h
MISCLVR = MISCLVR_3V; //3Vで低電圧リセットする
PDK_USE_FACTORY_IHRCR_16MHZ();
PDK_USE_FACTORY_BGTR();
AUTO_INIT_SYSCLOCK();
// Insert placeholder code to tell EasyPdkProg to calibrate the IHRC or ILRC internal oscillator.
// The AUTO_CALIBRATE_SYSCLOCK(...) macro uses F_CPU (defined in the Makefile) to choose the IHRC or ILRC oscillator.
// Alternatively, replace this with the more specific EASY_PDK_CALIBRATE_IHRC(...) or EASY_PDK_CALIBRATE_ILRC(...) macro from easy-pdk/calibrate.h
return 0; // Return 0 to inform SDCC to continue with normal initialization.
}PFS123は、Padaukのシングルコアマイコンの中では最も高機能なマイコンで、AD、コンパレータ、PWMが内蔵されています。
マイコンの書き込み機には、「Easy PDK Programmer」に、インサーキット書き込み機能を追加した「Super Easy PDK Programmer」を使っています。
昇降圧DCDCコンバータ
本文では5Vの昇降圧DCDCコンバータを使っていますが、3.3Vでもなんとかなると思います。
「電池2〜3本で動作する3.3V電源モジュール」が使えます。
商品ページにある「ECOモード」に改造してください。
シリンジのノズル
シリンジに入ったクリームはんだは粘性があるので、注射器の針のようなノズルでは、強い力が必要でなかなか出てきません。上のようなテーパーのあるノズルを使うことで、弱い力でもクリームはんだが出てきて、作業効率がとても上がります。
本格的に蓄電実験がしたい方
太陽電池とスーパーキャパシタで本格的に実験がしたい方は、「ソーラー発電・蓄電実験セット」がおすすめです。







コメント