Proactive Cybernetics

Arduino UNOでフルカラーLED七変化

タグ :組み込みソフト 2020年10月10日 by Proactive-cybernetics

あらまし

家にある引き出しを漁っていたら、フルカラーLEDを見つけました。
このフルカラーLEDをArduino UNOのPWMで光らせれば楽しくなると考え、久しぶりに
Arduinoのスケッチを書いてみました。

ArduinoとArduino UNO

Wikipediaの記事による説明では、Arduinoはハードウェアの名称でもあり、開発ソフトウェアや
それらを含むコミュニティだとも言われています。

Arduino公式サイトではArduinoという名称のハードウェア(コントローラー基板など)を
販売してたり、Arduino IDEという開発環境を配布していたりします。
その周りに、Arduino IDEをサポートする他社のコントローラーキット (ESP32やSTM32 Nucleo)が存在しています。
ESP32, STM32などのマイコンはArduino IDE以外の開発ツールが使えますが、
間違いなくArduinoのコミュニティに参画していると言えるでしょう。

Arduino UNOはArduinoの公式ハードウェアとして最も一般的なもので、
16MHzで動く8ビットマイコンのAVR ATmega328Pを搭載しています。
また、32kBのフラッシュメモリと2kBのSRAMを搭載しています。

Arduinoが搭載しているマイコンや記憶素子ではRaspberry PiのようにPC用のOSを動かすことはできませんが、
ArduinoはI2CやSPI, UARTといったシリアル通信インターフェース、A/Dコンバータ、PWM、割り込み端子を備えています。
電子回路をつなげてソフトウェアで制御するという用途ではRaspberry Piにも引けを取らない可能性があり、
低消費電力、低発熱に関して言えばRaspberry Piよりもはるかに優位です。

Arduino開発環境の用意


まずArduino公式サイトのダウンロードページからArduino IDEをダウンロード、インストールします。
(ページ内の「Download the Arduino IDE」の見出しのところです。)

Arduino IDEのインストールが終わったら、Arduino IDEを起動します。


続いてArduino UNOをPCに接続し、仮想シリアルポートの設定を行います。
Arduino IDEの「ツール」メニューを開き、ボード一覧から「Arduino UNO」を指定します。


Arduinoが接続されているシリアルポートを一覧から選択します。
「ツール」メニューの「シリアルポート」から、ポートの名前を選択します。

ArduinoとLEDの接続


いったんArduino UNOのボードをPCから外して、
以下の回路図の通りに、ArduinoとフルカラーLED, 330オーム抵抗器を接続します。



今回使用したフルカラーLEDはアノードコモン (プラス側の端子が3色で共通) タイプで、
抵抗器は330オームのものを使っています。

Arduinoのスケッチ


スケッチのソースコード全体はGithubにあります。
以下はソースコード内の要点になります。

RGBとHSV


今回の目論見として、色合いを
赤→橙色→黄色→緑→青緑色→青→紫色→赤
の順番で1巡させながら、明るさを一定に保つような
動作をさせます。

このような動作をさせるために、スケッチ内で
HSV (Hue-Saturation-Value)という色の表現方法を使用します。
HSVは手短に言えば色の色相 (色合い)を0°以上360°未満の角度で表し
S(彩度)とV(明るさ)を一定にしながら、H(色相)をインクリメントしていきます。

一方フルカラーLEDの調光はRGBですので、HSVの値をRGBの値に変換する処理が必要です。

HSV→RGBの変換では、WikipediaのHSV色空間の記事にもあるとおり、
Hの値が60°変わるごとに場合分け処理をする必要があります。

Arduino言語で実装すると、以下のようになります。
(コード内のhueが色相 (HSVのうちのH)で、r,g,bが変換後のRGB値です)

    if (hue <= 60) {
      r = 255;
      g = hue * 255 / 60;
      b = 0;
    }
    else if (hue <= 120) {
      r = (120 - hue) * 255 / 60;
      g = 255;
      b = 0;
    }
    else if (hue <= 180) {
      r = 0;
      g = 255;
      b = (hue - 120) * 255 / 60;
    }
    else if (hue <= 240) {
      r = 0;
      g = (240 - hue) * 255 / 60;
      b = 255;
    }
    else if (hue <= 300) {
      r = (hue - 240) * 255 / 60;
      g = 0;
      b = 255;
    }
    else {
      r = 255;
      g = 0;
      b = (360 - hue) * 255 / 60;
    }

(上記のコードではS=100%, V=100%で一定を前提に作っています。
S,Vの値が100%以外の値を取りうる場合は、コード内の数式がもう少し複雑になります。)

PWM出力による調光


PWM(パルス幅変調)とは、一定周期の矩形波(方形波)を出力しながら
矩形波のHIGHレベルを出力している長さの割合(デューティ比)を
入力(アナログ信号や数値)によって変化させる動作です。

Arduinoでは5つのディジタル出力端子でPWM動作をすることができ、
各々のPWMの入力値はプログラム中のanalogWrite()関数で指定します。

analogWrite()は0〜255の範囲で入力値を受け付け、
入力が0のとき常にLOW(0V)を出力、入力が255のとき常にHIGH(+5V)を出力します。
0〜255の間の値では「入力×100/255」[%] のデューティ比で矩形波を出力します。

ここで一つ注意が必要なのは、
今回のLED接続ではPWM出力は負論理になることです。
つまり、PWM出力がHIGHのときはLEDは光らず
PWM出力がLOWのときだけLEDが光ります。

そのため、analogWrite()で指定するPWM出力レベルは、
以下のように255からRGB値を引いた数とします。

    analogWrite(3, 255 - r);
    analogWrite(5, 255 - g);
    analogWrite(6, 255 - b);  


実際に光らせてみた

スケッチのコードをArduino IDEに入力して書き込みボタンを押すと
Arduino UNO基板上でプログラムが動作し始めます。




実際に光らせたときの動画はTwitterで公開しています。

まとめ

この記事では

  • Arduinoの概要
  • Arduino IDEのインストール
  • ArduinoUNOとの接続セットアップ
  • フルカラーLEDを調光するスケッチ作成と実行

について述べました。

ArduinoのPWM出力はLEDの調光以外にも
モーターの制御など様々な用途があります。

今回は取り上げませんでしたが、Arduinoにはシールドという
拡張基板がサードパーティにより設計・製造されております。
(秋月電子スイッチサイエンスなどのオンライン店舗でも販売されています)
(秋月電子のページでセッションのエラーが起きた場合はブラウザで再読み込みしましょう)

シールドには通信インターフェースの追加やモーターの駆動など
様々な機能を提供しています。これらシールドによる拡張性も
Arduinoプラットフォームの大きな特長と言えるでしょう。

おっさんの小言 : 昔は大変だった


Arduino以前のマイコン開発では、マイコンを動作させるための回路と
制御対象の周辺回路は一括で、一品ものとして作るのが主でした。

マイコンの書き込みも、一旦書き込み専用回路(ROMライタ)に
マイコンチップを載せ替えてから書き込みを行い、
その後また基板を載せ替えて動かす場合も多かったのです。

今のように試しに動かしてみながら微修正を加えていくようなことは、
当時はひどく面倒で非現実的だったのです。
(2000年代前半のPICやH8の制作例を見れば、当時の電子工作趣味人の苦労が偲ばれるでしょう。)

私見ですがArduinoの登場した頃になってから、マイコンの周辺回路と
制御対象を「別々のモジュールとして作り」「組み合わせて」
使うことが一般的になったように思えます。
この流れのおかげで、マイコン電子工作は昔よりも
非常に容易に、手軽に試せるものになりました。

ソフトウェアの世界のように、PCさえあれば
大抵何でもできるというほどではありません。
しかしながら高度な専門知識を持った人が
工具一式を揃えて初めてスタートラインに立てる、
というようなものではなくなりました。

↑先頭に戻る