フルカラー発光(蛍型発光)
近年、青色の発光ダイオードが開発され、赤、青、緑、の色の強さを調節することで、発光ダイオードを用いてフルカラーの発光が可能になりました。ここでは、この発光ダイオードを用いて、超小型プロセッサのプログラムでフルカラーを発光させる実験を行います。
フルカラーLEDとしてOSTA5131A(OptoSupply社)を利用します。一番長い線が共通のカソード(GND)で、上からR(赤)、GND,B(青),G(緑)
の順です。色により発光効率が異なる為、同じ電流を流しても白色にはなりません。許容最大電流は50mAです。
色を設定するには、RGB各LEDの発光強度を調整すればよいのですが、この強度の調整法にPWM: Power Width Modulation
があります。この方法は、一定区間の中で通電する割合(時間幅)を変更して平均的な電力を調整する方法です。下図は、25%、50%、75%
の電力制御の説明図です。横方向が時間で、立ち上がっている間スイッチをオンにして通電します。
通電幅を0にすればオフ、繰り返し期間と通電期間を同じにすれば、完全オン状態になります。PWM制御は少々荒っぽい手法なので、制御可能な対象は限定されますが
LED の発光強度を調整することは可能です。
PICにはハードウエアによるPWM制御も可能ですが制御可能な信号は1本のみです。ここでは、3本の制御が必要ですから、ソフトウエアでPWMを実現します。1周期の制御は次のようになります。Periodは繰り返し期間で、今回
255 とします。OnPeriod が通電期間で、0から OnPeriod の時刻まで通電することにします。LEDはポートBのB0端子に接続します。
output_high(PIN_B0); Period=0; while(Period<255){ if(Period == OnPeriod) output_low(pin_B0); Period ++; delay_us(10); }
最初、output_high(PIN_B0); でB0端子をオン、Periodを0にします。次に繰り返しの中で、Periodを増し、これが、OnPeriod
になったら、B0端子を0にし通電を停止します。OnPeriodが255に近づくと強い発光になります。繰り返し周期は、delay_us(10);で定まり、ここでは10μ秒です。
カソードコモン型LEDを同じパターンで複数点灯する場合は次のように、PNP型トランジスタ(2SA1015)を利用します。トランジスタ1個で10個くらいのフルカラーLEDを同時に点灯できます。この場合、PICの端子がLのときLEDが点灯しますから、プログラムで設定しているPICの端子の値(output_high
と output_low)を逆にする必要があります。
異なる点灯パターンにするには、LEDを異なるPICの端子に接続します。この場合、端子毎にプログラムを作成する必要があります。Aポートまで利用すれば、4パターンまで増設できます。
//蛍発光 #include <16F873A.h> //#include <16F88.h> //FullColor LED 最長:GND red,gnd,blue,green //サイン波に従う点燈 // #fuses HS,NOWDT,NOLVP,NOPROTECT,NOBROWNOUT #use delay(clock = 20000000) #include <stdlib.h> #define nump 34 int aryr[]={0,25,49,72,92,112,130,167,172,186, 200,220,240,220,200,180,181,173,164,155, 119,92,84,75,66,58,50,42,35,28,21,15,9,4}; int aryg[]={0,25,39,42,52,63,73,87,92,96, 100,120,140,160,180,190,201,213,184,165, 140,132,104,85,76,68,40,42,35,28,21,15,9,4}; int aryb[]={0,15,19,12,12,22,20,27,22,26, 20,30,34,40,40,40,50,53,54,55, 59,52,64,65,66,88,100,120,94,72,50,30,19,4}; int i,j,k; int lmr,lmg,lmb; int rv; long dly; void main(){ while(1){ //PWM loop output_toggle(PIN_C1); for(i=0;i<nump;i++){ //pwm start lmr=aryr[i]; lmb=aryb[i]; lmg=aryg[i]; rv=50; //rv=rand()%10 + 15; for(j=0;j<rv;j++){ output_high(PIN_B0); output_high(PIN_B1); output_high(PIN_B2); //pwm stop for(k=0;k<255;k++){ if(k==lmr) output_low(PIN_B0); if(k==lmb) output_low(PIN_B1); if(k==lmg) output_low(PIN_B2); } //k output_low(PIN_B0); output_low(PIN_B1); output_low(PIN_B2); }//j }//i for(i=0;i<4;i++){//変数は1バイト //delay_ms(rand()); } delay_ms(500); }//while }