マイコンボードArduino Nanoを使って、フルカラーLEDの各色の明るさを可変抵抗(ボリューム)で調整してみようという試みです。
可変抵抗で分圧した電圧をAD変換し、PWMでLチカの明るさを変化させてみます。
また、確認のためAD変換した値をLCDキャラクタディスプレイに表示させてみました。
このページは、マイコン Lチカ道場 Arduino編「2-1:可変抵抗でLチカの明るさをコントロール」に対応するページです。
今回の回路図は下記になります。
前回のランダムLチカの回路に、ボリュームを3つ追加した形になります。
部品リスト
使用する部品は下記になります。
品名 | 参照名 | 数量 | 数値・仕様 |
抵抗 | R1 | 1 | 330Ω |
抵抗 | R2,R3 | 2 | 220Ω |
可変抵抗 | RV1,RV2,RV3 | 3 | 10kΩ,Bカーブ 例:アルプス電気製RK09Dなど |
フルカラーLED | D1 | 1 | OptoSupply製 OSTBABS4C2B |
LCDモジュール | – | 1 | HiLetgo製 20X4 キャラクタLCDディスプレイ |
使用するボリューム(可変抵抗)
今回使用するのは、アルプス製の基板取り付け用ボリュームです。
ブレッドボードに挿すので、写真のように端子を曲げて使います。
10kΩのBカーブ品です。
つまみを回すと抵抗値が変化しますが、今回のBカーブ品は、抵抗値か直線的に変化します。
Aカーブ品は指数関数的に初めは徐々に抵抗値が増加します。オーディオ回路のボリュームにはAカーブを使います。
Cカーブというものもありますが、私は使ったことが無いです。(Aと逆)
プログラム(スケッチ)
やりたいこと
- 可変抵抗で分圧した電圧をArduino NanoでAD変換する。
- RGB三色それぞれ別の可変抵抗を使ってコントロールしたい。
- AD変換した値(10bit:0~1023)を、PWM幅(0~255)に変換する。
(map関数を使用) - PWMでLチカの明るさをコントロールする。
- LCDキャラクタディスプレイを追加して、上記のRGB各色のPWM幅を%で表示させる。
プログラム
#include <Wire.h> //I2C通信用のライブラリ
#include <LiquidCrystal_I2C.h> //I2C接続LCD用のライブラリ
LiquidCrystal_I2C lcd(0x27,20,4); // I2Cアドレス0x27か0x3F、20文字、4列
const int LED_B = 9; //LEDを接続するピン(PWM出力490Hz:3,9,10,11、980Hz:5,6)
const int LED_G = 10;
const int LED_R = 11;
const int ADC0 = A0; //AD変換に使用する入力ピン番号設定
const int ADC1 = A1;
const int ADC2 = A2;
int AD_data0 = 0; //AD変換値保存用の変数、RGB3色分
int AD_data1 = 0;
int AD_data2 = 0;
int PWM_B = 0; //PWM用の変数、RGB3色分
int PWM_G = 0;
int PWM_R = 0;
void setup() {
pinMode(LED_B, OUTPUT); //LED_Bピンを出力にする
pinMode(LED_G, OUTPUT); //LED_Gピンを出力にする
pinMode(LED_R, OUTPUT); //LED_Rピンを出力にする
//LCD用
lcd.init();//LCD初期化
lcd.backlight();//LCDバックライト点灯
lcd.setCursor(0,0);//カーソルを0列、1行目へセット
lcd.print("----- NobuLabo -----");//テスト用文字列を表示
lcd.setCursor(0,1);//カーソルを0列、2行目へセット
lcd.print("ABCDEFGHIJKLMNOPQRST");//テスト用文字列を表示
lcd.setCursor(0,2);//カーソルを0列、3行目へセット
lcd.print("UVWXYZ0123456789abcd");//テスト用文字列を表示
lcd.setCursor(0,3);//カーソルを0列、4行目へセット
lcd.print("ADC test L\xc1\xb6"); //カタカナ「チカ」を文字コードで入力してみた。
delay(1000); //1秒間待ち(表示のため)
}
void loop() {
//AD変換した値を実行して値を保存(0~1023)
AD_data0 = analogRead(ADC0);
AD_data1 = analogRead(ADC1);
AD_data2 = analogRead(ADC2);
//AD_data(0~1023)を0~255の範囲に変換してPWM値とする。小数は切り捨て。
PWM_R = map(AD_data0, 0, 1023, 0, 255);//AD_data0を範囲変換してPWM_Rへ代入
PWM_G = map(AD_data1, 0, 1023, 0, 255);//AD_data1を範囲変換してPWM_Gへ代入
PWM_B = map(AD_data2, 0, 1023, 0, 255);//AD_data2を範囲変換してPWM_Bへ代入
//LEDをPWMで点灯
analogWrite(LED_B, PWM_B);
analogWrite(LED_G, PWM_G);
analogWrite(LED_R, PWM_R);
//LCD表示用
lcd.home(); //カーソルをホームポジション(左上)へ移動
lcd.clear(); //表示をクリア
lcd.setCursor(0, 0); //カーソルを0列、1行目へセット
lcd.print("R="); //文字列R=を表示
lcd.print(PWM_R/2.55 ,1);//2.55で割って小数点一桁まで表示
lcd.print("%"); //文字列%を表示
lcd.setCursor(0, 1); //カーソルを0列、2行目へセット
lcd.print("G=");
lcd.print(PWM_G/2.55 ,1);
lcd.print("%");
lcd.setCursor(0, 2);
lcd.print("B=");
lcd.print(PWM_B/2.55 ,1);
lcd.print("%");
delay(50);//50mm秒間待ち
}
動作説明はコメント文を参照ください。
Arduino NanoのA/Dコンバータは10bitなので、0~5Vの電圧が0~1023の数字に変換されます。
PWMの値は0~255のため、単純に÷4でも良いかと思いましたが、map関数という関数を使用することで、0~1023の数値を0~255の範囲に変換してます。
【map関数の構文】
map(変換する変数, 現在の範囲の下限, 現在の範囲の上限, 変換後の範囲の下限, 変換後の範囲の上限)
変換後の上限と下限の値を入れ替えることで、値の反転にも使えるようです。
便利ですね。
LCDキャラクタディスプレイの部分は、前回と同じなのでそちらを参照ください。
動作確認
ブレッドボードに組んだ状態の写真です。
可変抵抗RV1のツマミを回すと、赤色LEDの明るさが増減します。
RV2は緑色、RV3は青色に対応しています。
RGB三色をお好みで調整して色を作ることができます。
【動画で見てみよう】
まとめ
マイコンボードArduino Nanoを使って、フルカラーLED各色の明るさを可変抵抗(ボリューム)で調整してみることに成功しました。
具体的には下記の内容を行いました。
・可変抵抗で分圧した電圧をAD変換
・map関数でPWMの数値に範囲変換(0~1023→0~255)
・PWMでRGB各色のLチカの明るさを変化
・確認のためPWMの値をLCDキャラクタディスプレイに表示
引き続き、難しいLチカに挑戦していきたいと思います。
参考リンク
Arduino Nano 純正品
今回使っているのは、ELEGOO製のArduino Nano互換ボードになります。
3個で純正品1個以下くらいのお値段です。
使用しているLCDキャラクタディスプレイモジュール