今回はワンボードマイコン「Arduino」にセンサーとLEDを接続する例を用いて、これらの技術を具体的に説明します。
IoTでは照度や温度を測定したり、照明器具の明るさを制御したりします。そのための基本的な技術として、A-D(Analog-Digital)変換やPWM(Pulse Width Modulation:パルス幅変調)があります。今回はワンボードマイコン「Arduino」にセンサーとLEDを接続する例を用いて、これらの技術を具体的に説明します。
ArduinoはMicrochip Technology(旧Atmel)の8ビットRISCマイクロコントローラ「AVR」を用いたワンボードマイコンです。1つのICの中にCPUとRAMや周辺回路だけでなくフラッシュROMも内蔵し、作成したプログラムを格納できます。入門によく用いられる「Arduino UNO」はAVRの中で32KバイトのフラッシュROMを持つ「ATmega328P」を採用しています。Arduino UNOはUSBシリアルコントローラを搭載しているので、PCにUSB接続し専用のIDEでプログラムを作成しAVRの機械語にクロスコンパイルしてから、内蔵のフラッシュROMに機械語命令を転送して動作させることができます。
Arduino UNOにはGPIO(General-Purpose Input/Output)やI/Oポートなどとも呼ばれるデジタル入出力端子が0番から13番まであります。アナログ入力端子は0番から5番まで用意され10ビットのA-D変換器に接続されています。アナログ出力端子はなく、デジタル入出力端子でPWMを用いて疑似的なアナログ出力を行います。
明るさを測定するセンサーをアナログ入力端子に接続し、LEDをPWMに対応したデジタル入出力端子に接続することで、暗さに応じてLEDを明るく点灯するプログラムを実行できます。
下図はArduino UNOに光センサーであるCdsセルとLEDを接続した回路図です。
光センサーはアナログ入力端子A0に接続され、LEDはPWM対応のデジタル入出力端子11に接続されています。なお、PWM対応の端子は〜マークの付いた3,5,6,9,10,11の6端子です。
Arduinoのプログラミング言語はC言語をベースに必要な関数の追加などを行った言語です。オブジェクト指向も取り入れているので、C++言語がベースと見ることもできます。main関数はなく、setup関数とloop関数が必須です。setup関数とloop関数を呼ぶmain関数がすでに定義されていると考えれば良いでしょう。setup関数は起動時に1度だけ呼ばれ、次に無限ループでloop関数が呼ばれます。
setup関数では、動作に必要な初期化を記述します。ここでは、デジタル入出力端子である11番端子を出力に設定しています。アナログ入力のA0端子は入力専用なので設定の必要はありません。
loop関数の中で、A0端子から入力された明るさデータを点灯データに変換して11番端子に出力しています。これが無限ループで何度も呼ばれることになります。
void setup() { pinMode(11, OUTPUT); // 11番を出力に設定 } void loop() { x = analogRead(0); // A0から0〜1023の1024段階に明るさデータを読む。 y = map(x, 500,900,255,0); // 明るさデータから点灯データに変換 if (y < 0 ) y =0; // マップの範囲を超した場合の修正 analogWrite(11, y); // 11番に0〜255の256段階で点灯データを出力する delay(100); // 0.1秒間停止 }
A-D変換で光センサーからのアナログ電圧をデジタル値に変換し、PWMでデジタル値を疑似的に電圧に変換してLEDの明るさを制御します。
Cdsセルは明るさで抵抗値が変化する素子です。安価なだけでなく、光の波長に対する特性が人間の目の特性に似ているので街路灯の自動点灯のような用途によく用いられます。Cdsは明るい状態で1kΩ程度の抵抗値で、暗くなると抵抗値が増大します。この抵抗値の変化を電圧の変化としてA0端子に入力しています。analogRead(0)関数は0〜5Vの電圧を0〜1023の1024段階のデジタル値に変換し、変数xに格納しています。
明るさを表すxの値は、map関数で点灯データに変換され、変数yに格納されます。LEDを点灯する11番端子はデジタル出力に設定されていますが、PWMを用いて0〜255の256段階で疑似的なアナログ電圧をanalogWrite(11,y)関数で出力しています。
PWMを用いると、デジタル出力端子で疑似的にアナログ電圧を出力することができます。デジタル入出力端子はデジタル信号を入力したり、出力したりする端子なので、出力電圧は電源電圧が5Vの場合、0VのLow電位かまたは5VのHight電位のみです。このままでは接続したLEDは100%の輝度で点灯するか、0%の輝度、つまり消灯するしかありません。
しかし、0Vと5Vを高速に切り替えると人の目には中間の明るさに見せることができます。右図のように信号をLowとHightを高速に切り替えるパルス信号にして、そのHightの割合を調節します。これがPWMです。日本語ではパルス幅変調と呼びます。Arduinoではパルス幅の比(デューティー)を変えることで平均電圧を0〜255の256段階で出力することができます。
10ビットのA-D変換器は0〜1023までの1024段階のデジタル値を出力します。それに対しPWMでは8ビットの0〜255までの256段階のデジタル値を用います。この両者をつなげる変換にmap関数を用います。
Cdsセルの明るい時の抵抗値を1kΩとすると、5Vの電源電圧を10kΩの抵抗で分圧することになり、下記の関係から4.5VがA-D変換器に入力されます。A-D変換の値は5Vの時1023なので、4.5Vなら920程度となります。暗くなると抵抗値が増加し電圧が下がるのでA-D変換の値も減少します。抵抗値が10kΩ程度に増加すればA-D変換の値は500程度となります。
例えば、A-D変換の値が900程度でLEDの照度が0%となり、500程度で100%になるように数値を変換します。照度100%は255を指定し、0%は0を指定します。つまり、x=500ならy=255に、x=900ならy=0になるように変換します。そのためにmap関数を用いて次のように記述します。
map関数 y=map(x, 500,900,255,0)
実際にはCdsセルの特性や部屋の明るさなどに合わせて数値を設定します。右図は変換の実例で、左側がxの値、右側がyの値です。なおmap関数は変換の範囲を超す明るさで負の値を出力するので、if文で0に補正して消灯にしています。
それでは、IoT関連の知識、スキルアップに役立つ問題を出題します! 今回はIoT検定 スキルマップの「デバイス − 制御装置」に該当する設問になります(※)。
問題:
ArduinoのようなIoTデバイスの入出力に関する説明として正しいものを1つ選びなさい。
※本連載の設問が実際のIoT検定にそのまま出題されるわけではありません。
Copyright © ITmedia, Inc. All Rights Reserved.
豊富なホワイトペーパーの中から、製品・サービス導入の検討に役立つ技術情報や導入事例などを簡単に入手できます。