LEDはすっかり普及し、様々な波長の様々な出力のものが販売されています。豆電球(白熱電球)よりも熱を持ちにくいのもいいところです。
一方で、豆電球と違って、調光(明るさの調整)がしにくいという特徴があります。LEDが光るためには一定の電圧が必要なので、ただ単に電源との間に可変抵抗を挟んだだけでは、思うように調光できないのです。光を絞っていくといきなり消灯してしまい、微妙な明るさを作り出すことができません。
そこで必要になるのがパルス幅変調=PWMです。PWMの詳細な説明はググってもらうといいですが、思いっきり簡単に説明すると、電圧や電源はそのままに高速で明滅を繰り返すことで、明るさを調整する仕組みです。1秒間に数百回から数万回の明滅を繰り返しますので、それなりの回路を組む必要があります。
そんなPWMを簡単に実現する方法があります。ワンボードマイコンのArduinoには、PWMの機能が組み込まれているのです。
Arduinoなら、C言語ライクなArduino言語でプログラミング可能で、パソコンからUSB経由でのプログラム書き込みも簡単。オープンソースなハードウェアなので、安価に入手可能です。さらに安価な類似製品も多く、それらは1個あたり$1.5程度で購入できます(たいてい個人輸入ですが)。
とにかくお手軽にPWM調光装置を作るならArduinoでもいいのですが、ATtinyシリーズのマイコンチップを使うと、更に小さくできます。Arduinoは名刺サイズ~親指サイズですが、ATtinyなら指の爪サイズ(よりも小さいサイズ)です。Arduino言語でのプログラミングも可能です。
ArduinoでもATtinyでもPWMの信号を作り出すことはできますが、単体で流せる電流はわずかで、高輝度のLEDをドライブするにはパワー不足です。そこで、トランジスタの一種であるパワーMOSFETを使って、大電流のon/offを切り替えます。
本稿では、ATTinyシリーズの中でも最小・最安のATTiny 13aを使ったPWM調光装置の作り方を、備忘録を兼ねて下記に紹介します。なお、私は顕微鏡用の照明装置として、このPWM調光器を作成して使用しています。今後、電気泳動ゲルの観察装置にも組み込む予定です。それでわかるように、PWMの応用範囲はとても広いのです。生物学者はPWMを使いこなすべきです(言い過ぎ)。
まずは、下記のコードをATtiny 13aに書き込みます。
私は自作した書き込みシールドをArduino UNOに装着し、これを書き込み装置として書き込みを行いました。その辺りの解説はネットに数多ありますので、ご参照ください。
とは言え、書き込み用の環境を整えるのは大変ですよね。アマチュアや任期付きの研究者、学生さんは、チップを送っていただければ私の方で書き込みを代行しますので、遠慮なく連絡してください。私がこの書き込みシールドを紛失しない限り、ですけど。
なお、PWMの実現にはArduino言語に標準装備されたanalogWrite()関数を使わず、コード内にも記載の通り、くろべこさんの高速PWMのhsPWM()関数をそのまま流用させてもらっています。
ポテンションメーター(いわゆるボリューム)につながったアナログピンA2で電圧を読み取って、過去20回分(0.5秒間)の読み取り値を平均し、明るさの設定値を求めています。ポテンションメーターで発生しがちなガリつきなどに影響されにくく、なめらかに明るさが変動するようにという工夫です。
ちなみに、下記のコードでATtiny 13aの小さなメモリ(わずか1KB!)を46%しか消費しません。まだまだ機能を盛り込めそうです。そんな機能は思いつきませんけどね。
#include <avr/io.h>
//過去20回分(0.5 sec)の計測値を格納する配列
int vals1[20] ;
//高速PWMのルーチンはくろべこさんのコードをそのまま流用
//https://kurobekoblog.com/attiny13_8bit_timer
uint8_t hsPWM(bool pin, int8_t pwm){
//*内臓クロック9.6MHz
//TCNT0 = 0; // タイマ0の初期値
if(pin==0){ //pin0, 右下
DDRB |= 0b00000001;//PB0出力設定
TCCR0A |= 0b10000011;//PB0非反転出力,高速PWM
TCCR0B |= 0b00000010;//8bit高速PWM,8分周比
OCR0A = pwm;//8bitタイマ/カウンタ比較レジスタA
return OCR0A;
}else{ //pin1, 右下から2番目
DDRB |= 0b00000010;//PB1出力設定
TCCR0A |= 0b10000011;//PB0非反転出力,高速PWM
TCCR0B |= 0b00000010;//8bit高速PWM,8分周比
OCR0B = pwm;//8bitタイマ/カウンタ比較レジスタA
return OCR0B;
}
}
// the setup function runs once when you press reset or power the board
void setup() {
}
// the loop function runs over and over again forever
void loop() {
//配列に格納した過去の値を一つずつずらして空きを作る
for (int i=0; i <= 18; i++){
vals1[19-i] = vals1[19-i-1];
}
//A2ピンの電圧を読み取る
int j = analogRead( A2 );
//空いた先頭に読み取った値を格納する
vals1[0] = j;
//配列内の値の平均を計算する
int mavg1 = 0;
for (int i=0; i <= 19; i++){
mavg1 = mavg1 + vals1[i];
}
mavg1 = mavg1 / 20;
//最大値1023の値を最大値255に変換
int8_t val = map(mavg1, 0, 1023, 0, 255);
//高速PWM
hsPWM(0, val);
//25 milli seconds待つ
delay( 25 );
}
下図のような回路を組みました。ブレッドボードでテストしてから、ユニバーサル基板にはんだ付けしました。
私がさしあたって使いたいのは12V駆動のLEDモジュールなので、12VのACアダプタを電源に使っています。12V電源を直接つなぐとATtinyが焼ききれてしまいますので、レギュレータで5Vに降圧して供給しています。LEDの電圧が5Vまでだったら、レギュレータを省いてOKです。ATtiny 13aの動作電圧範囲は1.8~5.5Vと広いので、あとは適当に抵抗などでLEDへの電流を制限してください。
図では3端子レギュレータ(右上の部品)ですが、実際には、手を抜いてモジュール化されたものを用いました(なので、コンデンサがありません。7805などの一般的な3端子レギュレータで作る場合は、発振防止・平滑化用のコンデンサを追加する必要があります)。
大電流のドライブには、NチャンネルのパワーMOSFETを使っています。実際に使ったのは、秋月電子で在庫処分特価になっていたTK4Q60DAですが、有名な2SK4017などで良いでしょう。
図では、同じATtinyシリーズのATtiny 85(13aの上位互換チップ)になっています。85でも同じように動くはずですが、安い13aで十分です。
(以下は、後日加筆予定)