ArduinoによるRGBW光ストリップの制御

以前、「色替えと調光が同時にできるLEDストリップが欲しい」というご要望をいただきました。このような機能を備えた製品はありませんが、実現するためのセットアップ方法はもちろんあります。具体的には、Arduino開発ボードを利用して、MOSFETで24Vのストリップを駆動する方法を見つけました。この例をご紹介する前に、いくつかのトピックを説明しておきます。

MOSFETの選択

MOSFETは非常に汎用性の高い部品であり、最初は何を手に入れ、どのように使えばいいのかわからないかもしれません。この記事では、特にArduinoを制御用の処理装置として使用しているので、5V以下のVgs(ゲートからソースまでの電圧)で駆動できるMOSFETを選択する必要があります。次に、MOSFETがどれだけの電流と電圧を扱えるかに注意してください。トランジスタよりも大きな電流や電圧で何かを駆動する場合、ゲート絶縁層が故障すると、トランジスタとArduinoの両方が焼失する可能性があります。次に、FETにヒートシンクを使用するかどうかを知るための公式があります。まず、ドレインからソースまでトランジスタを通過する電力を計算する必要があります。

image

ここで、Idsは負荷に流れる電流値、Rdsonはゲート電圧を印加して動作させたときのドレイン-ソース間の抵抗値となります。そして、次の情報が必要となります:最大接合部温度定格(データシート)、周囲温度(室温)、そしてデータシートにある接合部から周囲への熱抵抗です。ここでは、その方程式を紹介します:

image

Pmaxは、ヒートシンクを必要としないでトランジスタが処理できる最大電力です。ほとんどのFETには、特定の周囲温度における最大定格が記載されていることに注意してください。つまり、Rdsonで最大電力を得るためには、その温度に強制的に下げる必要があるということです。上の式は、その温度以上でディレーティングを行うためのものです。コントロールする対象がわかったら、アプリケーションの要求に応じて、FETがどのくらい熱くなるかをチェックすることが重要です。また、定格電力とRdsonがわかっているので、同じ電力の式を使ってPmaxの式で最大電流を計算することができます。他にも、ピン配列やトランジスタの大きさ(それが重要であれば)、Rdsonの値などがあります。Rdsonはアプリケーションによって大きく異なりますが、一般的には、Rdsonが低いほど電流の低減を最小限にするように求めていて、Rdsonが高いほどそれによる電流の低減をあまり気にしていないことを意味します。

回路設計:値の議論

私のセットアップは以下の通りです:




私の回路図では、MOSFETのゲートをPWM対応の端子に接続し、調光制御ができるようにしています。PWMについてご存じない方のために、私が書いたブログ記事をご紹介します:パルス幅変調(PWM)とは何か?偶然にも300Ωで十分だとわかりました。最初に500Ωの抵抗を購入しましたが、大きすぎて電流と電圧が下がりすぎてしまい、MOSFETを作動させることができませんでした。幸いなことに、小さめの抵抗器を余分に持っていたので、いろいろな値を試してみました。 FETの使い方を学び始めたばかりの人には、1つのトランジスタのゲートに1kΩのポテンショメータを直列に挿入して、LEDストリップの色がそれぞれ動作するまで1色ずつ調整することをお勧めします。MOSFET を理解していることを確認するために、各ワイヤを通して各ストリップの色を一度に 1 つずつテストしました。

FQP30N06L-NDを選んだのは、Rdsonがかなり低く、駆動電圧がDC5Vでこのアプリケーションに良いと思ったからです。電源については、一度に1つの光の色だけをテストしたいと思いました。このストリップには電流を制御するための抵抗が内蔵されているので、あとは十分な容量の電源を用意し電圧を合わせるだけです。993-1302-NDは、DC24V、最大定格650mAに対応しています。4色すべてを同時に使用する場合は、少なくとも 2.36Aか、それ以上の電源が必要です(私が購入したパーツの場合)。それぞれのLEDストリップにはさまざまな定格がありますが、ここではその概要をご紹介します:

  • 順方向電圧:この電圧あるいはそれ以上の電源が必要ですが、それ以上の電源の場合は、適切な電圧に調整または低減する必要があります。
  • 推奨LED電流:通常、パラメータに「テスト」電流として記載されています。最大電流も記載されているかどうかに注意してください。一度に1つの色を使用したい場合は、その色の定格電流のみを知れば十分ですが、すべての色を使用したい場合は、各色のすべての電流定格を知る必要があります(同時に使用する場合はそれらの電流を加算する必要があります)。
  • 消費電力:ヒートシンクを必要としないことを確認するために、先に説明した最大電力の方程式を思い出してください。
  • MOSFETの駆動電圧:FETを駆動するために使用する電圧は、Vgsのパラメータに一致するか、それに近いものである必要があります。
  • Rdson:MOSFETがどのくらい電流を低下させるかを確認するための値(一部のアプリケーションでは重要)。
  • 電源:私は基本的なウォールマウント型電源を使用しましたが、定電圧のLEDドライバを用意した方が良いかもしれません。必要な電流に注意してください。私は、一度に1つの色しか使わないようにプログラムを設計しましたので、電源の最大値を超えることはありませんでした。
私の実験用セットアップの部品表は以下の通りです:
商品概要 Digi-Key品番 メーカー品番 数量
Res 300 Ohm 1/2W 5% Axial CF12JT300RCT-ND CF12JT300R 4
MOSFET N-CH 60V 32A TO-220 FQP30N06L-ND FQP30N06L 4
IP20 Light Strip 24V RGBW 3000K 2007-AB-FA02408-19712-8A1-ND AB-FA02408-19712-8A1 1
AC/DC Wall Mount Adapter 24V 16W 993-1302-ND PSA15A-240P6 1
Conn Jack R/A PCB 5.5X2.1MM 839-1516-ND 54-00133 1
Pot 10K Ohm 1/2W Plastic Linear 987-1665-ND P260P-D1AS2AB10K 1

注:次の3つの部品は、Arduinoを使用している場合や、ソルダーレス・ブレッドボードへの配線を容易にするために推奨されます。

商品概要 Digi-Key品番 メーカー品番 数量
Conn Barrier Strip 5Circ. 0.375" WM5723-ND 0387200205 1
Arduino Uno R3 ATMEGA328P Eval 1050-1024-ND A000066 1
USB A-Male To B-Male Cable 1’ TL1205-ND UR022-001 1

最後に、興味のある方に、配線が正しくできているか、MOSFETでPWMが動作するかを確認するために書いたプログラムをご紹介します。

int anPin = A0; //setup input pin for analog read
int pwm1 = 11, pwm2 = 10, pwm3 = 6, pwm4 = 5; //set var names for output pins, I am using them for PWM so I named them accordingly
bool upColor = 0; //flag for updating color
int colState = 1; //red = 1, green = 2, blue = 3, white = 4
void setup() {
  setPinStates(pwm1, pwm2, pwm3, pwm4, OUTPUT); //call function to set pwm output pins
  pinMode(anPin, INPUT);
  Serial.begin(9600);
}

void loop() {
int val = analogRead(anPin); //update the analog value right at the beginning of loop
val = map(val, 0, 1023, 0, 255); //map values of analog read to the available range for analogW write
Serial.println(val);
switchColors(val); //run function to see if the value drops to zero, I want to switch colors at 0 for fun
Serial.println(colState);
switch(colState) {
case 1: //red = 1, so have the analog write pwm1 with the mapped value
analogWrite(pwm4, val);
multWriteOther(pwm1, pwm2, pwm3, LOW);
break;
case 2: //green = 2, analog write to pwm2 with mapped value
analogWrite(pwm3, val);
multWriteOther(pwm1, pwm2, pwm4, LOW);
break;
case 3: //blue = 3, analog write to pwm3 with mapped value
analogWrite(pwm2, val);
multWriteOther(pwm1, pwm4, pwm3, LOW);
break;
case 4: //white = 4, analog write to pwm4 with mapped value
analogWrite(pwm1, val);
multWriteOther(pwm4, pwm2, pwm3, LOW);
break;
default:
break;
}
if(val > 0) //code to reset upColor back to 0 for the next color if the analog reaches 0.
upColor = 0;
}

void setPinStates(int p1, int p2, int p3, int p4, bool os1) { //quick function to set pin states all at once
pinMode(p1, os1);
pinMode(p2, os1);
pinMode(p3, os1);
pinMode(p4, os1);
}

void switchColors(int value) { //function that uses the value to switch colors (uses new MOSFET basically)
if(value == 0) { //if the value read now becomes zero, the following happens:
while(upColor == 0 && value == 0) { //activate a loop to ensure followings steps happen; uses a boolean flag as a “check” that updates whenever a new analog value above zero is read
int temp = analogRead(anPin); //read from the analog pin, while loop would continue forever without this check
if(temp > 0 && upColor == 0) { //check if both the temp read and upColor flag still = 0
if(colState < 4) { //if the color state is less than 4, we can update the count by 1 and immediately update the colorstate to 1 ending the while loop
colState += 1;
upColor = 1;
} else if(colState == 4) { //if the color state is at 4, need to set it back to 1 and immediately update the colorstate to 1 ending the while loop
colState = 1;
upColor = 1;
}
} else if(temp == 0) {//extra redundancy to make sure no weird addition happens to color state; keeps upColor set to 0 so while loop can keep running
colState = colState;
upColor = 0;
}
}
}
}

void multWriteOther(int p1, int p2, int p3, bool horl){//function to make three pins go LOW, used to make sure other lights are “off” all the way between stages, don’t need to blow my power supply
digitalWrite(p1, horl);
digitalWrite(p2, horl);
digitalWrite(p3, horl);
}






オリジナル・ソース(英語)