Arduinoその他工作

Arduino LeonardoはUSBの周辺機器にも早変わり!? まずは音量の調整から始めよう!

Arduinoは、USBのインターフェースを持っているので、キーボードやマウスなどのパソコンの周辺機器も自作できます。

もちろん、キーボードそのものを作ることもできますが、いきなり作るのは大変です。そこで本記事では、一部のキーボードに付いている音量を調整する部分をArduinoで作ってみます。

Arduinoと可変抵抗器(ポテンショメーター)があれば簡単です。早速、始めましょう。

translated-usb-volume-control-with-arduino-01

Arduino Leaonardoの外観

 

目次

  1. 準備
  2. USBを使った通信でパソコンをコントロール
  3. エンコーダーにも使用される可変抵抗器
  4. スケッチ全体
  5. プログラムを詳細に見てみよう
  6. Arduinoと可変抵抗器をつなげよう
  7. まとめ

 

1. 準備

本記事では次のものを使用します。

Arduino Leonardo

translated-usb-volume-control-with-arduino-02

可変抵抗器

translated-usb-volume-control-with-arduino-03

Arduino IDE

translated-usb-volume-control-with-arduino-04

今回は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」と接続します。

translated-usb-volume-control-with-arduino-05

Arduinoに接続された可変抵抗器(イメージ)

配線が終わったら、Arduinoボードを再びパソコンに接続します。
通常の電子工作であれば、Arduinoを常にパソコンに接続しておく必要はありませんが、今回は、USB接続で動く周辺機器を作ったので、USBケーブルでパソコンに接続する必要があります。

いよいよ本番です。
可変抵抗器の値とパソコンの音量が最小の状態で、Arduinoボードをパソコンに接続して可変抵抗器を動かすと、音量が大きくなり上手く動作するはずです。
可変抵抗器を操作しても、意図したように音量が動かない場合は、配線の確認や、可変抵抗器の端子の位置をデーターシートで確認してください。

スケッチの中にdelay()関数を呼び出している行があります。可変抵抗器の動作に合わせて、スムーズに音量が変化しない場合は、ここを調整してください。
サンプルのスケッチはコメント状態(//から行末まで)になっているので、Arduinoボードの動作には影響を与えません。このコメント記号(//)を取り除くことで有効化できます。

 

7. まとめ

Arduinoボードには、さまざまな種類があり、Leonardoのように、標準でキーボードやマウスの作成をサポートするライブラリが用意されているものがあります。
さらに、サードパーティー製のライブラリを使えば、音消・PLAY・PAUSE・STOPボタンなどのマルチメディアキーも実装できます。

今回の記事では、ライブラリを利用することで、USB接続で動作する周辺機器もArduinoを使えば簡単に制作できることを紹介するため、シンプルな構成にしました。
USBの周辺機器の製作は、一見すると難しく感じます。一つ一つ、ゆっくりと進めていけば、単純な制御の組み合わせなので、怖がらず、ぜひ、挑戦してください。

ゼロから作るライントレーサー
Device Plus 編集部

エレクトロニクスやメカトロニクスを愛するみなさんに、深く愛されるサイトを目指してDevice Plusを運営中。

https://deviceplus.jp