ArduinoでUSB接続のPC音量調整ボタンを作る方法


本記事について

Arduinoという、手軽にマイコンを使った電子工作ができる、マイコン機器開発ボードがあります。
本記事では、そのArduinoを使って、PCの音量を大・小・消音できる、USB接続の音量調整ボタンの作り方についてまとめました。

使用するArduino

Arduinoには色々な種類があるのですが、「ATmega32U4」というマイコンを搭載した「Arduino Micro」を使います。
ATmega32U4はUBSを扱う機能が備わっていて、ArduinoでUSB機器を作ることができます。

回路図

回路は単純で、ピン7・8・9をGNDにつなぐボタンがあり、それぞれのボタンが、PCの音量を大・小・消音にするボタンになります。

続いてプログラム手順に入る前に、HIDというものについて簡単に説明します。

HIDについて

USBを使ってどんな機器を作るかは開発者の自由なのですが、マウスやキーボードなどのよく使われるUSB機器は、HID(Human Interface Device)として予めUSBの規格で定義されています。

HID機器のデバイスドライバーはPCのOSに標準で入っているので、HID機器はどのPCでもつなぐだけで、追加のプログラムをインストールすることなしに使うことができます。

幸い音量調整ボタンもHIDで定義されているので、今回はそちらのHID機器として音量調整ボタンを作成しました。

音量調整ボタンのHIDについて

音量調整ボタンは、HIDでは「キーボード」ではなく、「コンシューマーコントロール」という別カテゴリーの機能扱いになるので、ArduinoにあるUSBキーボードのライブラリを使って、音量調整ボタンを押すということはできません。

また、キーボードやマウスのライブラリはArduinoのIDE(Arduinoの開発ツール)に入っているのですが、コンシューマーコントロールのライブラリはないので、他のライブラリを参考にしながら、別途実装する必要があります。

では、具体的なプログラム手順に入ります。

プログラム手順

メインプログラム(スケッチ)

下記メインプログラムを任意の名前で作成します。

VolumeControlButton.ino
#include "ConsumerControl.h"

u8 previousButtonState = 1;  // 連打防止フラグ

void setup() {
  pinMode(7, INPUT_PULLUP);  // 音量大にするピン7
  pinMode(8, INPUT_PULLUP);  // 音量小にするピン8
  pinMode(9, INPUT_PULLUP);  // 音量消音にするピン9
}

void loop() {
  if(digitalRead(7)==LOW){
    ConsumerControl.press(VOLUME_UP); // 音量大ボタンを押す
    ConsumerControl.release(); // ボタンを離す
    delay(100);

  } else if(digitalRead(8)==LOW){
    ConsumerControl.press(VOLUME_DOWN); // 音量小ボタンを押す
    ConsumerControl.release(); // ボタンを離す
    delay(100);

  } else if(digitalRead(9)==LOW){
    if(previousButtonState==0){
      ConsumerControl.press(VOLUME_MUTE);  // 音量消音ボタンを押す
      previousButtonState = 1;

    } else {
      ConsumerControl.release(); // ボタンを離す
      previousButtonState = 1;
    }
  }else {
    if(previousButtonState==1){
      ConsumerControl.release(); // ボタンを離す
      previousButtonState = 0;
    }
  }
}

コンシューマーコントロールプログラム

下記の「ConsumerControl.h」「ConsumerControl.cpp」を、上記のメインプログラムと同じフォルダに置きます。

ConsumerControl.h
#include "HID.h"

#define REPORT_ID 1
#define VOLUME_UP 0
#define VOLUME_DOWN 1
#define VOLUME_MUTE 2

class ConsumerControl_
{
public:
  ConsumerControl_(void);
  void press(u8 buttonBit);
  void release(void);
};

extern ConsumerControl_ ConsumerControl;
ConsumerControl.cpp
#include "ConsumerControl.h"

static const uint8_t _hidReportDescriptor[] PROGMEM = {
  0x05, 0x0c, // USAGE_PAGE (Consumer)
  0x09, 0x01, // USAGE (Consumer Control)
  0xa1, 0x01, // COLLECTION (Application)
  0x85, REPORT_ID, // REPORT_ID (X)
  0x15, 0x00, // LOGICAL_MINIMUM (0)
  0x25, 0x01, // LOGICAL_MAXIMUM (1)
  0x09, 0xe9, // USAGE (Volume Increment)
  0x09, 0xea, // USAGE (Volume Decrement)
  0x09, 0xe2, // USAGE (Mute)
  0x75, 0x01, // REPORT_SIZE (1)
  0x95, 0x03, // REPORT_COUNT (3)
  0x81, 0x02, // INPUT (Data,Var,Abs)
  0x75, 0x01, // REPORT_SIZE (1)
  0x95, 0x05, // REPORT_COUNT (5)
  0x81, 0x03, // INPUT (Const,Var,Abs)
  0xC0 //   END_COLLECTION
};

ConsumerControl_::ConsumerControl_(void)
{
  static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
  HID().AppendDescriptor(&node);
}

void ConsumerControl_::press(u8 buttonBit)
{
  u8 m[1];
  m[0]=(1 << buttonBit);
  HID().SendReport(REPORT_ID, m, sizeof(m));
}

void ConsumerControl_::release()
{
  u8 m[1];
  m[0]=0;
  HID().SendReport(REPORT_ID, m, sizeof(m));
}

ConsumerControl_ ConsumerControl;

実行

後は、ArduinoのIDEでプログラム(スケッチ)をコンパイルしてAdruinoに転送して書き込めば、USB接続のPC音量調整ボタンができあがります。

書き込んだプログラムはArduinoをPCから外しても永続するので、Arduinoを他のPCに挿しても音量調整ボタンとして認識されて使うことができます。

応用

メインプログラムの中で、音量調整を行っている部分は

  • ConsumerControl.press(<ボタン名>)で「ボタン名」の音量調整ボタンを押す
  • ConsumerControl.release()で全ての音量調整ボタンを解除

だけですので、メインプログラムを書き換えて、好みのPC音量調整機器を作ることもできます。

また、HIDは1つのUSB機器に対して複数持つことも可能なため、キーボードのライブラリと組み合わせて、音量調整もできるキーボードを作ることも可能かと思います。

元記事