Arduinoは、USBのインターフェースを持っているので、キーボードやマウスなどのパソコンの周辺機器も自作できます。
もちろん、キーボードそのものを作ることもできますが、いきなり作るのは大変です。そこで本記事では、一部のキーボードに付いている音量を調整する部分をArduinoで作ってみます。
Arduinoと可変抵抗器(ポテンショメーター)があれば簡単です。早速、始めましょう。
目次
1. 準備
本記事では次のものを使用します。
Arduino Leonardo
可変抵抗器
Arduino IDE
今回はArduino Unoではなく、Arduino Leonardoを使用します。
Arduino Leonardoは、キーボードやマウスなど、USBに接続する周辺機器を作成できるHID機能が備わっているので、任意の文字列のPC入力や、マウスのスクロール操作のようなUSBインターフェースデバイスとして使うことが可能です。
可変抵抗器は、後ほど解説します。
上記に加えて、micro USB(マイクロUSB)ケーブルを用意してください。
本記事は、スケッチの操作、動作確認にWindowsを使用しています。ほかのOSでは、動作が異なる場合もあるので注意が必要です。
2. USBを使った通信でパソコンをコントロール
Arduinoは、接続しているパソコンとUSBで通信する機能を搭載しています。
Arduino Unoなど、ほとんどのArduinoボードは、USBの通信とスケッチを実行するマイコンが別々に搭載されています。このようなArduinoボードでは、パソコンのUSBに接続する周辺機器を作るには大変な作業です。
技術的にはArduino UnoでもHoodloader2ライブラリを組み合わせれば、USB機器として動作できますが、この方法は難易度が高いので、最初からUSBのインターフェースを内蔵しているマイコンを搭載したArduinoボードを使用するのがおすすめです。
本記事では、Arduino Unoから派生した、Leonardoを使用。
Arduino Leonardoはスケッチを実行するマイコンに、ATmega32u4が搭載されています。
ATmega32u4はUSB通信機能を内蔵しているマイコンなので、その機能をうまく応用することでマウスやキーボードのような、USB接続の周辺機器を簡単に制作できます。
標準ライブラリだけでもマウスやキーボードののような入力デバイスを簡単に作成できますが、今回は一歩進んで、音量調整やPLAY・PAUSE・STOPボタンなどの機能を持つマルチメディアキーを作ってみましょう。
マルチメディアキーに対応するには、Arduino IDEにライブラリを追加する作業が必要です。
ライブラリには、特殊な処理を実行するためのソースコードがまとめられています。
サーボモーターの制御や、キーボード・マウスの自作をサポートするものなど、数多くのライブラリが、Arduino IDEに組み込まれています。
あらかじめ用意されているライブラリだけでなく、サードパーティーが提供するものや、自作のライブラリの追加もできるので、Arduinoを使った電子工作の可能性は無限に広がります。
今回は、サードパーティー製のHID-Projectと呼ばれるライブラリを使用。
[スケッチ]メニューから[ライブラリをインクルード]>[ライブラリを管理…]を選択してください。
次に[検索をフィルタ]に「hoodloader」と入力してください。
すると、「HID-Project by NicoHood」が見つかるはずなので、最新のバージョンを選択して、[インストール]をクリックします。
これで、HID-projectライブラリが、使用できるようになりました。
3. エンコーダーにも使用される可変抵抗器
可変抵抗器は、英語で「potentiometer: ポテンショメーター」と呼ばれています。本来、ポテンショメーターは、回転角や移動量を調整するデバイスの総称ですが、内部に可変抵抗器が使用されていることから、英語では「可変抵抗器=ポテンショメーター」と呼ばれるようになったようです。
日本でも、回転角や移動量を調整する目的で使用する場合には、「ポテンショメーター」と呼ぶ場合もあります。
本記事では、混乱を避けるために「可変抵抗器」と呼び方を統一します。
また、「可変抵抗器」に似たデバイスに「半固定抵抗器」がありますが、基本的に両者の機能は同じと考えていいでしょう。筐体からシャフトと、1番・2番・3番の3本の端子が出ています。シャフトを回すことで「1番」と「2番」、「2番」と「3番」の端子間の抵抗値が変わります。
ただし、端子名は製品によって異なる場合があるので、使用前に、データーシートで確認してください。
可変抵抗器と半固定抵抗器の違い
可変抵抗器と半固定抵抗器の違いは、その強度にあります。
可変抵抗器は、機器の目立つ場所に取り付けられ、音量の調整など、頻繁に動かされることを想定した、丈夫な作りになっています。一方、半固定抵抗器は、基板上などに実装され、電子回路の調整に使われることが多いです。頻繁に操作する部分ではないので、強度より小型化が重視されています。
可変抵抗器は、人間がシャフトを回転することによって、端子から出力される信号(電圧)が変わります。
その電圧を、マイコンボードが読み取ることで、シャフトの位置を検出。このとき、電圧は0Vから5V(電源電圧)まで、アナログ的に変化します。製品によって違いはありますが、出力される電圧が2.5Vの時は、シャフトの位置が中間となります。
マイコンボードで、このアナログ的な変化を読み取るには、「A/D変換」という機能を使用します。
A/D変換は、アナログ入力ピンの現在の電圧を、そのまま数値で表現できるのです。
可変抵抗器は、必ずしも人間が回転する必要はありません。シャフトの部分を、モーターに取り付ければ、「モーターが何度回転したのか」を読み取ることが可能です。この機能を「エンコーダー」と呼びます。
ホビー用のサーボモーターは、この仕組みを利用して、正確な位置決めを実現しています。
4. スケッチ全体
Arduino Unoに転送するスケッチは以下の通りです。
#include <HID-Project.h> int potpin = 0; // Assign analog pin to potentiometer int val = 0; // Variable to read value from potentiometer, starts at 0 int oldVolume = 0; // Used to compare volume levels int currentVolume = 0; // Used to compare volume levels void setup() { Serial.begin(9600); // This will allow you to read the current value of the dial } void loop() { val = analogRead(potpin); // Reads potentiometer value (between 0 and 1023) val = map(val, 0, 1023, 0, 50); // Scale value to volume (value between 0 and 50) Serial.print(val); // Print dial/volume position Serial.println(); // if (val != oldVolume) { if(val > oldVolume) { //delay(100); Consumer.write(MEDIA_VOLUME_UP); currentVolume = currentVolume + 1; if (currentVolume > 50) { currentVolume = 50; } oldVolume = currentVolume; } else { //delay(100); Consumer.write(MEDIA_VOLUME_DOWN); currentVolume = currentVolume - 1; if (currentVolume < 0) { currentVolume = 0; } oldVolume = currentVolume; } } }
上記のソースコードをArduino IDEにコピー&ペーストしてください。
5. プログラムを詳細に見てみよう
可変抵抗器の読み取りや、その値をパソコンに送る方法など、スケッチの重要な部分を解説します。
Arduinoボードに転送する前に確認しましょう。
①インクルードファイルの読み込み
最初の行は、インクルードファイルの読み込みです。
#include <HID-Project.h>
マルチメディアキーの処理を提供するHID-projectライブラリを、先ほど読み込みましたが、それだけではスケッチで利用できません。忘れずにインクルードファイルの読み込みをしてください。
②グローバル変数の定義と初期化
次に、グローバル変数の定義と初期化が続きます。
int potpin = 0; // Assign analog pin to potentiometer int val = 0; // Variable to read value from potentiometer, starts at 0 int oldVolume = 0; // Used to compare volume levels int currentVolume = 0; // Used to compare volume levels
最初の行は、可変抵抗器からの入力を受け取るアナログ入力ピンの番号を指定。ここでは「A0(0番)」を指定しています。
可変抵抗器の現在の位置情報は、2行目の変数valに格納されます。最初に0で初期化しておきましょう。
USBのインターフェースでは、直接、パソコンに音量の値を指定できないことになっています。
そのため、スケッチからパソコンには、「少し大きく」や「少し小さく」のように指示します。
Windowsで設定できる音量の範囲は、0から100なので、その範囲を超えるまで、パソコンは指示を受け付けます。
Arduinoからの「少し大きく」や「少し小さく」の指示で、パソコンは2段階ずつ音量が変わるようです。
また、Arduinoから、パソコンの現在の値を取得することもできません。スケッチの中では「今、何回指示を出したか」を数えることで、パソコンの音量を0から100の範囲に収めます。
残りのoldVolumeとcurrentVolumeは、その「何回指示を出したか」を記憶する現在の音量をカウントする変数です。どちらの変数も、最初に0で初期化しておきます。
looop()関数内のコードを解説
val = analogRead(potpin); // Reads potentiometer value (between 0 and 1023) val = map(val, 0, 1023, 0, 50); // Scale value to volume (value between 0 and 50)
この2行は、可変抵抗器の現在の位置を読み取っています。
analogRead()関数は、指定されたアナログ入力ピンの状態を取得。変数potpinには0が格納されているので、ここではアナログ入力ピン「A0(0番)」の電圧を読み込みます。
Arduinoのアナログ入力は、ピンにかかる電圧(0Vから5V)を、0から1023の1024段階(1段階は4.9mV)で読み取ります。変数valには、読み取った値が格納されます。
ただし、0から1023は、パソコンに対する指示としては細かすぎるので、map()関数を使用して、0から50までの範囲に丸めてください。map()関数は整数を出力するので、丸める際に小数部分は切り捨てられます。
ここで、最大値を50にするのは、Arduinoからの指示によって、パソコンの音量が2段階ずつ変化するためです。音量が0の状態から100になるまでに、50回「少し大きく」と指示を出します。
③音量の指示出し
以下のコードは、可変抵抗器の現在の値に応じて、パソコンに音量を「少し大きく」や「少し小さく」と指示を出す部分です。
if (val != oldVolume) { if(val > oldVolume) { //delay(100); Consumer.write(MEDIA_VOLUME_UP); currentVolume = currentVolume + 1; if (currentVolume > 50) { currentVolume = 50; } oldVolume = currentVolume; } else { //delay(100); Consumer.write(MEDIA_VOLUME_DOWN); currentVolume = currentVolume - 1; if (currentVolume < 0) { currentVolume = 0; } oldVolume = currentVolume; } }
④読み取った可変抵抗器の値と、音量をカウントする変数の値を比較
読み取った可変抵抗器の値と、スケッチ内部の現在の音量をカウントする変数の値を比較します。
変化がなければ、外側のif文は実行されず、プログラムは何もしません。可変抵抗器が少しでも変化すると、if文の中が実行されます。
可変抵抗器が「少し大きく」の方向に回転した場合は、Consumer.write()関数を呼び出して、パソコンにMEDIA_VOLUME_UPを送信してください。
これによって、「パソコンの音量が上がった」はずなので、現在の音量をカウントする変数の値は増加します。
この動作は、loop()関数が呼び出されるごとに、可変抵抗器の値と、現在の音量をカウントする変数の値が一致するまで実行されます。
反対に、可変抵抗器の値が「少し小さく」の方向に回転した場合は、パソコンにMEDIA_VOLUME_DOWNを送信し、現在の音量をカウントする変数の値を減少します。
この動作も、可変抵抗器の値と、現在の音量をカウントの値が一致するまで繰り返します。
6. Arduinoと可変抵抗器をつなげよう
ソースコードの実装が終わり、スケッチが完成したらArduinoボードに転送しましょう。
その後、一旦、パソコンにつながっているUSBケーブルを取り外して、可変抵抗器を次の手順で配線してください。
- 可変抵抗器の「1番」端子をArduinoボードの「GND」と接続します。
- 可変抵抗器の「2番」端子をアナログ入力ピンの「A0(0番)」と接続します。
- 可変抵抗器の「3番」端子をArduinoボードの「5V」と接続します。
配線が終わったら、Arduinoボードを再びパソコンに接続します。
通常の電子工作であれば、Arduinoを常にパソコンに接続しておく必要はありませんが、今回は、USB接続で動く周辺機器を作ったので、USBケーブルでパソコンに接続する必要があります。
いよいよ本番です。
可変抵抗器の値とパソコンの音量が最小の状態で、Arduinoボードをパソコンに接続して可変抵抗器を動かすと、音量が大きくなり上手く動作するはずです。
可変抵抗器を操作しても、意図したように音量が動かない場合は、配線の確認や、可変抵抗器の端子の位置をデーターシートで確認してください。
スケッチの中にdelay()関数を呼び出している行があります。可変抵抗器の動作に合わせて、スムーズに音量が変化しない場合は、ここを調整してください。
サンプルのスケッチはコメント状態(//から行末まで)になっているので、Arduinoボードの動作には影響を与えません。このコメント記号(//)を取り除くことで有効化できます。
7. まとめ
Arduinoボードには、さまざまな種類があり、Leonardoのように、標準でキーボードやマウスの作成をサポートするライブラリが用意されているものがあります。
さらに、サードパーティー製のライブラリを使えば、音消・PLAY・PAUSE・STOPボタンなどのマルチメディアキーも実装できます。
今回の記事では、ライブラリを利用することで、USB接続で動作する周辺機器もArduinoを使えば簡単に制作できることを紹介するため、シンプルな構成にしました。
USBの周辺機器の製作は、一見すると難しく感じます。一つ一つ、ゆっくりと進めていけば、単純な制御の組み合わせなので、怖がらず、ぜひ、挑戦してください。