作成日時:2015年12月13日 16時16分13秒
更新日時:2020年05月19日 08時58分37秒
この記事は9年ほど前に投稿されました。内容が古くなっている可能性がありますので更新日時にご注意ください。
前回はデジタルIOでLEDのオン・オフを行いましたが、今回はPWM制御でLEDの光量を調整してみたいと思います。
はじめに
Raspberry Piはメイン用途としてはPCなのでハードウェアのPWM制御は1つのみ(実際には3つあるらしいがWiringPiでは使えなかった)しかありませんでしたが、Arduinoは制御がメインなのでPWM信号が6つもあります。
PWMの分解能こそPiには及びません(Piが1024段階 Arduinoが256段階(0-1023と0-255))が、使用できるポートが6個もあるので使いみちはいろいろあると思います。
色々と使える機器はたくさんありますが。今回は簡単にLEDの制御をしてみたいと思います。
必要なもの
LEDと適当な抵抗(前回のものでOK)
接続
抵抗を介してArduinoの~が書かれてあるピン(3・5・6・9・10・11)のいずれかに接続します。
(前回のママ放置してある人ならあのままでOK)
制御
PWM制御をする場合は特に何もする必要がなく制御用のコマンドを記述すれば制御できます。
前述のとおり、PWMの分解能は256段階、制御周波数は490Hz程度となっています。
- analogWrite(ポート番号,値);
これでPWM出力ができます。
なお、数値は0がdigitalWriteの0と同じで出力なし。
255がdigitalWriteの1と同じとなっています。
実行例
一眼レフのISO感度・シャッタースピード・絞りを一定にし、PWMの数値のみを変更して撮影した結果。
PWM制御の実行例 | |||
255 | 128 | 64 | 32 |
16 | 8 | 4 | 0 |
コーディング
前回の構成で発光色の切替時にフェードイン・アウトを行うプログラムを載せておきます。
// LEDのタイプ設定
// アノード:0 カソード:1
#define LedType 0
// PWMの最小値と最大値の設定
// カソードコモン:最大255 最小 0
// アノードコモン:最大 0 最小255
#if LedType
#define PWM_MAX 255
#define PWM_MIN 0
#else
#define PWM_MAX 0
#define PWM_MIN 255
#endif
// LEDポート定義
#define R_LED 11
#define G_LED 10
#define B_LED 9
// フェードイン・アウトのディレイ設定(ms)
#define FadeTime 8
// フェードイン命令設定
// 下:カソードコモン 下:アノードコモン
#if LedType
#define FadeInSetting ++<PWM_MAX
#else
#define FadeInSetting --
#endif
// フェードアウト命令設定
// 上:カソードコモン 下:アノードコモン
#if LedType
#define FadeOutSetting f-->PWM_MIN
#else
#define FadeOutSetting f++<PWM_MIN
#endif
// the setup function runs once when you press reset or power the board
void setup() {
//一旦全消灯
analogWrite(R_LED,PWM_MIN);
analogWrite(G_LED,PWM_MIN);
analogWrite(B_LED,PWM_MIN);
}
// the loop function runs over and over again forever
void loop() {
// 変数定義 i=繰り返し回数 rgb=各色 f=フェードアウト用
unsigned short i,r,g,b,f;
// メイン処理系
while (1) {
i++;
r=g=b=PWM_MIN;f=PWM_MAX;
//フェードイン
//i変数を8で割って3bitにしたあと、3bitの状況で
//どのLEDを光らせるかを決定
if((((i%8)>>0)&1)==1)while(r FadeInSetting){analogWrite(R_LED, r);delay(FadeTime);}
if((((i%8)>>1)&1)==1)while(g FadeInSetting){analogWrite(G_LED, g);delay(FadeTime);}
if((((i%8)>>2)&1)==1)while(b FadeInSetting){analogWrite(B_LED, b);delay(FadeTime);}
delay(1000);
//フェードアウト
while(FadeOutSetting){
if((((i%8)>>0)&1)==1)analogWrite(R_LED,f);
if((((i%8)>>1)&1)==1)analogWrite(G_LED,f);
if((((i%8)>>2)&1)==1)analogWrite(B_LED,f);
delay(FadeTime);}
}
}
なお、前回と同様にアノードコモンのフルカラーLEDを使用する場合やPNPトランジスタでスイッチングする場合に合わせてプログラムが記述されています。カソードコモンやNPNトランジスタを使用する場合は先頭のLedTypeの数値を変えてください。
ArduinoでPWM pic.twitter.com/bWgURu67OY
— 潤滑油漏三郎@多摩提督 (@Sakura87_net) 2015, 12月 13