Nintendo Switch用のエフェクトーンをさらに作り込んでみる

 

前回、綺麗に作り込めたと思った矢先にミスに気づいてしまったNintendo Switch専用エフェクトーン。実は、USBがドックの内部にあること以外にも気づいたことがありまして。

th_effectone-3_1

よくよく見てみると、スピーカーの部分に合わせて穴が開いています。

このSwitch用のエフェクトーンは、元になったゼルダ一番くじの景品のエフェクトーンの機構をそのまま採用しており、リードスイッチでSwitch本体のドックへの着脱を認識するようになっています。

th_effectone-3_7

そのため、写真のようにリードスイッチを反応させるための磁石を本体に取り付ける必要がありました。でも、本来この磁石は、ない方が良いに決まっています。

th_effectone-3_2

磁石をなくすために、この穴、うまく使えないでしょうか。ということで、考えてみました。

最初は溝の底にタクトスイッチでも埋め込めないかと考えたのですが、このドックの溝はSwitch本体にほぼジャストフィットするようになっています。そのため、例え表面実装の小さなタクトスイッチであっても、底に置いてしまうと、本体をドックに収納した時に本体が斜めになってしまい、本体とドックの接続がうまくいかなくなってしまう恐れがあったので、タクトスイッチを使うのはやめました。

他、導電性の薄い紙を差し込んで、Switch本体がドックに収まると紙同士が接触するようにする、なんてのも考えてみましたが、Swtich本体を長くドックに収納していると、それで紙にクセがついてしまって常時通電状態になる可能性が考えられたので、こちらも却下です。

となると、非接触、例えば距離センサをあの穴に埋め込んで距離の変化を見るという手もありそうですが、こんな小さなところに埋め込める距離センサなんてあるのかしら。。。と思っていたら。

ありました。サイズを見たところ、ギリギリSwitchドックに収まるか収まらないぐらいの大きさです。

この距離センサ、正確に距離を出すものではなく、対象物との距離が5cm以下だとLOW、5cmを少し越えるとHIGHを出力するという代物です。この性質だけだと、例えドックの穴にこのセンサを取り付けたとしても、Switch本体がドックに挿さっていようがいまいが距離は常時5cm以下なので出力は常時LOW、ということになってしまい、使いものになりません。しかしこのセンサ、とても都合が良いことに、「距離が0.5cm以下になると逆にHIGHが出力される」という仕様になっています(詳しくはこちらをご参照ください)。つまり、Switch本体をドックに挿したときに、Switch本体とこのセンサの距離が0.5cm以下になってくれれば、Switch本体の着脱をうまく認識してくれそうです。

 

th_effectone-3_3

ということで、とりあえず買ってみました。さて、うまいこと穴に入ってくれるかどうか。。。

th_effectone-3_4

ちょっと突っかかりますが、ググッと押し込むと。。。

th_effectone-3_5

バッチリ入りました。キツめに入る形になるので、ちょっとコードを曲げたぐらいでは全然外れません。

 

th_effectone-3_8

このセンサの利用に合わせて本体の配線を組み替える必要があったので、とりあえずまたブレッドボードで組んでみました。この写真では見えませんが、TrinketのGNDと#0(距離センサの入力)の間は10kΩ抵抗が接続されていて、#0をプルダウンするようにしています。

それから、一応ソースコードも以下のように変更しています。

#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>

#define IN_SOUND  1
#define OUT_SOUND 2

#define VOLUME_1 10
#define VOLUME_2 15
#define VOLUME_3 20
#define VOLUME_4 25
#define VOLUME_5 30

#define OPEN_CLOSE_PIN 0
#define LED_PIN 1
#define VOLUME_PIN 2
SoftwareSerial mySerial(3,4); // RX, TX

uint8_t last_open_close_state = HIGH;
uint8_t open_close_state      = HIGH;
uint8_t last_volume_state     = HIGH;
uint8_t volume_state          = HIGH;
uint8_t volume = VOLUME_3;

void setup () {  
  mySerial.begin (9600);
  mp3_set_serial (mySerial);
  mp3_set_volume (volume);

  pinMode(OPEN_CLOSE_PIN, INPUT);
  pinMode(VOLUME_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
}

void loop () {        

  open_close_state = digitalRead(OPEN_CLOSE_PIN);
  if(last_open_close_state == HIGH && open_close_state == LOW){
    mp3_play(OUT_SOUND);
  }else if(last_open_close_state == LOW && open_close_state == HIGH){
    mp3_play(IN_SOUND);
  }
  last_open_close_state = open_close_state;

  volume_state = digitalRead(VOLUME_PIN);
  if(last_volume_state == HIGH && volume_state == LOW){
    digitalWrite(LED_PIN, HIGH);
    switch(volume){
    case VOLUME_1: volume = VOLUME_2; break;
    case VOLUME_2: volume = VOLUME_3; break;
    case VOLUME_3: volume = VOLUME_4; break;
    case VOLUME_4: volume = VOLUME_5; break;
    case VOLUME_5: volume = VOLUME_1; break;
    default: volume = VOLUME_3;
    }
    mp3_set_volume (volume);
    delay(100);
    digitalWrite(LED_PIN, LOW);
  }
  last_volume_state = volume_state;

  delay(20);
}

 

これをSwtichのドックに取り付けます。

th_effectone-3_6

動作確認です。ドキドキ。

 

うまく動いてくれました。どうやら、ドック収納時のSwitch本体と距離センサの間の距離がうまいこと0.5cm以下になってくれたようです。よかったよかった。

 

ということで、リードスイッチを使うときに比べ、費用コスト的には3〜4倍高くなってしまうのですが、Switch本体には一切何も取り付ける必要なく、エフェクトーンを実現することができました。後はこれを綺麗に作り込んで、この取り組みはおしまいにしたいと思います。思ったより長くなってしまいました。。。

 

なお、次週は本業の都合で更新はお休みの予定です。ご了承ください。