
Arduino Microとスイッチを使ったnature prhysm専用コントローラの作り方を紹介します。
このページはある程度の電子工作の知識を持った人が参考程度に見ることを想定しています。
そうでない人も何となくの雰囲気は感じ取れると思います。
※ここに書いてある内容を行ったことによる損害うんたらかんたらの責任は一切負いません。また、ここに書いてあることの正確性も一切保証していません。
用意するもの
適当な箱(ティッシュ箱など)
(針金)
押して潰れないようにする支え
光らせたいときに必要なもの

スイッチの取り付け
配線をする前に必要なのがスイッチを箱に取り付けることです。
箱にカッター等で四角い穴をあけスイッチをはめ込んでいきます。
このとき同じように穴をあけた段ボールを間に挟むと強度が上がります。
さらに強度を上げたいときはアクリル板に頑張って穴をあけて挟みます。
箱内部の補強は先にやってしまうと配線が難しくなるので後で行います。
箱はティッシュ箱以外でも四角く穴があけられるもので押しても凹まない強度があれば作れます(多分)。

配線
地獄の配線作業です。
気合で配線していきます。
ひとつの例として自分の行った配線を右の図に示しています。
スイッチは下から赤、緑、青の順に並んでいます。
フルカラーLEDを付けない場合は上半分のLEDの部分は無視してください。
Arduino MicroとフルカラーLEDを基板上に配線し、スイッチをArduinoのそれぞれのピンに配線します。図では直接Arduinoのピンに配線を繋いでいますが、ピンに直接はんだで繋ぐのは無理なのでピンソケットを仲介します。Arduinoを配置する場所にピンソケットを配置します。スイッチ等の配線はピンソケットの端子に行います。
フルカラーLEDは信号入力、出力ピンが繋がれていて電源、グランドピンの間にはノイズ対策用のセラミックコンデンサが挟まれています。
配線が完了したらコントローラ内部の補強を行いましょう。細長い木の角材等の支えを箱と同じ高さに切って裏に張り付けます。

Arduino Microへプログラムを書き込む
配線が終わればあとはArduino Microに「スイッチを押した時にキーボードの"RTYUFGHJVBNM"を押したという情報をPCに送るようなプログラム」を書き込むことでコントローラが完成します。Arduino IDEをダウンロードしてフルカラーLED用のライブラリをダウンロードします(Arduino向けライブラリをクリック)。
図の通りに作ると下のプログラムをそのままコピーして使うことができます。
Arduino IDEの使い方やライブラリの導入方法は他のサイトを参照してください。
#include <HID-Project.h>
#include <HID-Settings.h>
#include <Adafruit_NeoPixel.h>
#define R1 2
#define G1 3
#define B1 4
#define R2 5
#define G2 6
#define B2 7
#define R3 8
#define G3 9
#define B3 10
#define R4 11
#define G4 12
#define B4 13
#define LED A5
Adafruit_NeoPixel RGBLED = Adafruit_NeoPixel(4, A5, NEO_RGB + NEO_KHZ800);
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(R1, INPUT_PULLUP);
  pinMode(R2, INPUT_PULLUP);
  pinMode(R3, INPUT_PULLUP);
  pinMode(R4, INPUT_PULLUP);
  pinMode(G1, INPUT_PULLUP);
  pinMode(G2, INPUT_PULLUP);
  pinMode(G3, INPUT_PULLUP);
  pinMode(G4, INPUT_PULLUP);
  pinMode(B1, INPUT_PULLUP);
  pinMode(B2, INPUT_PULLUP);
  pinMode(B3, INPUT_PULLUP);
  pinMode(B4, INPUT_PULLUP);
  RGBLED.begin() ;                   // RGBLEDのライブラリを初期化する
}
void loop() {
  // put your main code here, to run repeatedly
  int i = 0;
  int R[4] = {0, 0, 0, 0};
  int G[4] = {0, 0, 0, 0};
  int B[4] = {0, 0, 0, 0};
  int data[2] = {0, 0};
  char a = 0;
  int lane = 0;
  int LN[4] = {0, 0, 0, 0}; //オートプレイのときLN中かどうか
  int Lighttime[4] = {0, 0, 0, 0}; //オートプレイでLEDを光らせる時間
  while (1) {
    RGBLED.setBrightness(20) ;
    for (i = 0; i <= 3; i++) {
      if (Lighttime[i] == 0 && LN[i] == 0) {//もう光らせる必要が無いとき
        R[i] = 0;
        G[i] = 0;
        B[i] = 0;
      } else {
        if (Lighttime[i] >= 1)Lighttime[i] -= 1;
      }
    }
    a = Serial.read();//シリアル通信で来たデータを読み込む
    if (a != -1) {
      if (a == '0')lane = 3;
      if (a == '1')lane = 2;
      if (a == '2')lane = 1;
      if (a == '3')lane = 0;
      data[0] = Serial.read();
      data[1] = Serial.read();
      if (data[1] == '0') {
        Lighttime[lane] = 20;
      }
      if (data[1] == '1') {
        LN[lane] = 1;
      }
      if (data[1] == '2') {
        LN[lane] = 0;
      }
      if (data[0] == 'R') {
        R[lane] = 255;
      }
      if (data[0] == 'G') {
        G[lane] = 255;
      }
      if (data[0] == 'B') {
        B[lane] = 255;
      }
      if (data[0] == 'Y') {
        R[lane] = 255;
        G[lane] = 255;
      }
      if (data[0] == 'C') {
        G[lane] = 255;
        B[lane] = 255;
      }
      if (data[0] == 'M') {
        R[lane] = 255;
        B[lane] = 255;
      }
      if (data[0] == 'W') {
        R[lane] = 255;
        G[lane] = 255;
        B[lane] = 255;
      }
      if (data[0] == 'F') {
        R[lane] = random(100, 255) ;
        G[lane] = random(100, 255) ;
        B[lane] = random(100, 255) ;
      }
    }
    if (digitalRead(R1) == 0) {
      //Serial.println(1);
      R[3] = 255;
      NKROKeyboard.add('v');
    } else {
      NKROKeyboard.remove('v');
    }
    if (digitalRead(R2) == 0) {
      //Serial.println(2);
      R[2] = 255;
      NKROKeyboard.add('b');
    } else {
      NKROKeyboard.remove('b');
    }
    if (digitalRead(R3) == 0) {
      //Serial.println(3);
      R[1] = 255;
      NKROKeyboard.add('n');
    } else {
      NKROKeyboard.remove('n');
    }
    if (digitalRead(R4) == 0) {
      //Serial.println(4);
      R[0] = 255;
      NKROKeyboard.add('m');
    } else {
      NKROKeyboard.remove('m');
    }
    if (digitalRead(G1) == 0) {
      //Serial.println(5);
      G[3] = 255;
      NKROKeyboard.add('f');
    } else {
      NKROKeyboard.remove('f');
    }
    if (digitalRead(G2) == 0) {
      //Serial.println(6);
      G[2] = 255;
      NKROKeyboard.add('g');
    } else {
      NKROKeyboard.remove('g');
    }
    if (digitalRead(G3) == 0) {
      //Serial.println(7);
      G[1] = 255;
      NKROKeyboard.add('h');
    } else {
      NKROKeyboard.remove('h');
    }
    if (digitalRead(G4) == 0) {
      //Serial.println(8);
      G[0] = 255;
      NKROKeyboard.add('j');
    } else {
      NKROKeyboard.remove('j');
    }
    if (digitalRead(B1) == 0) {
      //Serial.println(9);
      B[3] = 255;
      NKROKeyboard.add('r');
    } else {
      NKROKeyboard.remove('r');
    }
    if (digitalRead(B2) == 0) {
      //Serial.println(10);
      B[2] = 255;
      NKROKeyboard.add('t');
    } else {
      NKROKeyboard.remove('t');
    }
    if (digitalRead(B3) == 0) {
      //Serial.println(11);
      B[1] = 255;
      NKROKeyboard.add('y');
    } else {
      NKROKeyboard.remove('y');
    }
    if (digitalRead(B4) == 0) {
      //Serial.println(12);
      B[0] = 255;
      NKROKeyboard.add('u');
    } else {
      NKROKeyboard.remove('u');
    }
    NKROKeyboard.send();
    RGBLED.setPixelColor(0, R[0], G[0], B[0]) ;
    RGBLED.setPixelColor(1, R[1], G[1], B[1]) ;
    RGBLED.setPixelColor(2, R[2], G[2], B[2]) ;
    RGBLED.setPixelColor(3, R[3], G[3], B[3]) ;
    RGBLED.show() ;
    delay(1);
  }
}
