少しずつ夜が長くなってくると、何だか無性にLEDをチカチカさせてみたくなる(笑)
Arduino での「Lチカ」色々です。
準備するもの
●Arduino – どれでも同じようだが結構違う。遊ぶにはブレッドボードに直差しできるものが便利。
●ブレッドボード – 無くても遊べるが、あればとても便利。
●LED – お好きなものを。
●電流制限抵抗 – LEDに流す電流値を制限するために必要。「LED 電流制限抵抗」で検索すれば値の求め方が見つかるはず。
●ジャンプワイヤ – 必要量。
Arduino のピン入出力電流制限は、HIGH(5V出力)の場合20mA、LOW(吸い込み)の場合100mA以内が推奨らしいです。
また、各ピンの電流合計値でも制約があります。
LED数個なら問題ないと思いますが、多数をドライブさせる場合は定格を超さないように注意が必要です。
1. ON/OFF
まずは単純なON/OFF。
ループ内で0.5秒ON、0.5秒OFFを繰り返します。
Blink.ino
void setup() { pinMode(13, OUTPUT); // initialize digital pin 13 as an output. } void loop() { digitalWrite(13, HIGH); // turn the LED on delay(500); // wait for a 0.5 second digitalWrite(13, LOW); // turn the LED off delay(500); // wait for a 0.5 second }
2. PWM-その1
最大輝度に向けて2.55秒、消灯に向けて2.55秒の変化を繰り返します。
Fade.ino
int led = 9; // the PWM pin the LED is attached to int brightness = 0; // how bright the LED is int fadeAmount = 1; // how many points to fade the LED by void setup() { pinMode(led, OUTPUT); // Set pinMode } void loop() { analogWrite(led, brightness); brightness += fadeAmount; if (brightness <= 0 || brightness >= 255) { fadeAmount = -fadeAmount; } delay(10); }
3.PWM-その2
3.6秒周期で柔らかな輝度変化を繰り返します。
Twinkle.ino
int led = 9; // the PWM pin the LED is attached to int brightness = 0; // how bright the LED is int degree = 0; float pi = 3.141592653; void setup() { pinMode(led, OUTPUT); // Set pinMode } void loop() { brightness = 128 + cos(float(degree) / 180 * pi) * 128; if (brightness > 255) { brightness = 255; } analogWrite(led, brightness); degree += 1; if (degree >= 360) { degree = 0; } delay(10); }
4.PWM-その3
1周期ごとに輝度を変化させる秒数をランダムに変えます。
Twinkle2.ino
int led = 9; // the PWM pin the LED is attached to int brightness = 0; // how bright the LED is int degree = 0; int dstep = 1; float pi = 3.141592653; void setup() { Serial.begin(9600); randomSeed(analogRead(0)); pinMode(led, OUTPUT); // Set pinMode } void loop() { brightness = 128 - cos(float(degree) / 180 * pi) * 128; if (brightness > 255) { brightness = 255; } analogWrite(led, brightness); degree += dstep; if (degree >= 360) { degree = 0; dstep = random(1, 10); } delay(30); }
5.PWM-割り込みを使う
ループ内で処理をせず、割り込みを使って輝度変化をさせます。
twinkle_led.ino
// Twinkle LED #include <MsTimer2.h> const float pi = 3.141592653; int ledPin = 9; int ledDegree = 0; int ledStep = 1; void flash() { int brightness = 128 + cos((float(ledDegree) / 180) * pi) * 128; if (brightness > 255) { brightness = 255; } analogWrite(ledPin, brightness); ledDegree += ledStep; if (ledDegree >= 360) { ledStep = random(1, 18); ledDegree = 0; } } void setup() { Serial.begin(9600); // open the serial port at 9600 bps: randomSeed(analogRead(0)); MsTimer2::set(30, flash); // 30ms period MsTimer2::start(); } void loop() { }
6.PWM-割り込みを使って複数のLEDを別々に制御する
[5.]の応用編です。PWM制御の出来るピンを複数指定します。
TwinkleTwinkle.ino
// Twinkle Twinkle LED #include <MsTimer2.h> const float pi = 3.141592653; const int ledMax = 3; int ledPin[] = {5, 9, 10}; int ledDegree[] = {0, 0, 0}; int ledStep[] = {1, 1, 1}; void flash() { int brightness = 0; for (int i = 0; i < ledMax; i++) { brightness = 128 + cos((float(ledDegree[i]) / 180) * pi) * 128; if (brightness > 255) { brightness = 255; } analogWrite(ledPin[i], brightness); ledDegree[i] += ledStep[i]; if (ledDegree[i] >= 360) { ledStep[i] = random(1, 18); ledDegree[i] = 0; } } } void setup() { Serial.begin(9600); // open the serial port at 9600 bps: randomSeed(analogRead(0)); MsTimer2::set(30, flash); // 30ms period MsTimer2::start(); } void loop() { }
7. 応用編:サインボードの作成
秋月電子通商のLEDネオンを使った工作です。
LEDの定格は12Vですが、眩しすぎるので9Vで使用しています。
消費電力も抑えられて良い感じです。
LEDの電圧が高いため、ピン出力を一旦トランジスタアレイで受け、LEDをドライブしています。
発光パターンを配列に入れておき、順次読み出しています。
このスケッチではLED6本、16パターンを繰り返します。
Open.ino
// Twinkle Twinkle LED -Open- // -juncoffee- Sep 25, 2019 #include <MsTimer2.h> #define ledOF 0 // Off #define ledFD 1 // Fade #define ledUP 2 // Up #define ledDN 3 // Down #define ledB1 4 // Blink1 #define ledB2 5 // Blink2 #define ledON 6 // On #define ledMax 6 // The number of the connected LED's const float pi = 3.141592653; int ledPin[] = {3, 5, 6, 9, 10, 11}; // Pin Number Circle, O, p, e, n, note int ledDegree = 0; int ledStep = 5; int ledStage = 0; const int ledPattern[16][6] = { // Circle O p e n note {ledON, ledUP, ledOF, ledOF, ledOF, ledOF}, // 0 {ledON, ledDN, ledUP, ledOF, ledOF, ledOF}, // 1 {ledON, ledOF, ledDN, ledUP, ledOF, ledOF}, // 2 {ledON, ledOF, ledOF, ledDN, ledUP, ledOF}, // 3 {ledON, ledOF, ledOF, ledOF, ledDN, ledB1}, // 4 {ledON, ledUP, ledUP, ledUP, ledUP, ledON}, // 5 {ledON, ledFD, ledFD, ledFD, ledFD, ledON}, // 6 {ledON, ledFD, ledFD, ledFD, ledFD, ledB1}, // 7 {ledON, ledON, ledON, ledON, ledON, ledB1}, // 8 {ledON, ledON, ledON, ledON, ledON, ledB2}, // 9 {ledON, ledFD, ledFD, ledFD, ledFD, ledON}, // 10 {ledON, ledFD, ledFD, ledFD, ledFD, ledON}, // 11 {ledON, ledFD, ledFD, ledFD, ledFD, ledON}, // 12 {ledON, ledON, ledON, ledON, ledON, ledB1}, // 13 {ledON, ledON, ledON, ledON, ledON, ledB1}, // 14 {ledON, ledON, ledON, ledON, ledON, ledB2} // 15 }; void flash() { int brightness = 0; for (int i = 0; i < ledMax; i++) { switch (ledPattern[ledStage][i]) { case ledOF: brightness = 0; break; case ledFD: brightness = 128 - (cos((float(ledDegree) / 180) * pi) * 128); if (brightness > 255) { brightness = 255; } break; case ledUP: brightness = 128 - (cos((float(ledDegree) / 360) * pi) * 128); if (brightness > 255) { brightness = 255; } break; case ledDN: brightness = 128 + (cos((float(ledDegree) / 360) * pi) * 128); if (brightness > 255) { brightness = 255; } break; case ledB1: if ((ledDegree % 90) < 15) { brightness = 255; else { brightness = 0; } break; case ledB2: if ((ledDegree % 45) < 15) { brightness = 255; } else { brightness = 0; } break; case ledON: brightness = 255; break; default: brightness = 0; break; } analogWrite(ledPin[i], brightness); } ledDegree += ledStep; if (ledDegree >= 360) { if (++ledStage >= 16) { ledStage = 0; } // ledStep[i] = random(1, 18); ledDegree = 0; } } void setup() { for (int i = 0; i < ledMax; i++) { pinMode(ledPin[i], OUTPUT); // sets the pin as output } Serial.begin(9600); // open the serial port at 9600 bps: randomSeed(analogRead(0)); MsTimer2::set(30, flash); // 30ms period MsTimer2::start(); } void loop() { }