Touch Boardで「かえるのうたマシーン」を作ってみた

投稿者:

前回の記事でTouch Boardを使う環境を整えたので、実際に導電インクとTouch Boardを組み合わせて「かえるのうたマシーン」を作りました。作り方について解説していきます。


次の3つの手順に沿って作っています。
1.鍵盤をつくる
2.音源を用意する
3.スケッチの修正

1.鍵盤をつくる
公式サイトにある、鍵盤用紙をプリントアウトし、枠に沿って導電インクを塗ります。枠外にマスキングテープを貼ると上手に塗ることができます。
touchboard-masking

鍵盤用紙のページ

導電インクはTouch Boardと同じBare Conductiveさんの製品を使います。ペンだけで塗るとインクの量の調整が難しいので、インクを紙上に少しだしてから、筆や綿棒などを使って伸ばします。絵の具と違い、水で薄める必要はありません。インクは水溶性なので、衣類についても水で洗い流すことができます。

音は2種類の方法で鳴らすことができます。1つめは指が導電インクが触れた時に鳴らす方法、2つめは導電インクを広げて塗って、指を触れなくても、手をかざすだけで音を鳴らす方法です。今回は、カエルが鳴く一部の音節を手をかざすだけで鳴らすようにします。触れなくても音が鳴るようにするために、導電インクで大きい形を描きます。形はなんでもOKですが、私はマスキングテープで形を作りやすいので、3cm四方の正方形にしました。

鍵盤の用意が終わったら、Touch Boardと接続します。タッチセンサと、鍵盤の丸いところを合わせ、導電インクを少量つけて接続します。インクの量が多いと、紙とボードの間から漏れて隣の鍵盤とショートするので、本当に少しだけで大丈夫です。これで鍵盤の準備はおしまいです。

TouchBoard-fix-180

2.音源をつくる
用意する音源はかえるの歌で使うドからラまでの6種類とかえるの鳴き声を2種類です。ドレミ音源はmacに入っているGarageBandで作成、カエルの鳴き声は以下のフリーサイトからお借りしました。

ポケットサウンド/効果音素材
soundbible.com

作成した音源はTRACK000.mp3~TRACK011.mp3という名前に変更します。末尾の番号がTouch BoardのタッチセンサのE0〜E11に対応します。使用しないポートのファイルは作成しなくてOKです。

SDカードリーダを使って、Touch Board付属のMicroSDカードとPCを接続します。SDカードに既に入っているTRACK000.mp3〜TRACK011.mp3は前回の記事で聞いた説明用音声ファイルです。この音声ファイルで読まれている説明書がREADME.txtに書かれています。
touchboard-files

この説明音声ファイルをSDカードから削除し、代わりにさきほど作った音源を入れます。

3.スケッチの修正
サンプルスケッチでは、センサにタッチしないと音が鳴らないので、手をかざすだけで音が鳴るようなスケッチを書き込みます。タッチセンサを近接センサとして使えるようにするスケッチをダウンロードして、Arduino IDEで開きます。

近接センサ用スケッチ

このスケッチはサンプルスケッチに、タッチセンサのしきい値を変更する記述が追記されただけのものです。69行目から80行目にその記述があります。

// Changes from Touch MP3
  
  // this is the touch threshold - setting it low makes it more like a proximity trigger
  // default value is 40 for touch
  MPR121.setTouchThreshold(8);
  
  // this is the release threshold - must ALWAYS be smaller than the touch threshold
  // default value is 20 for touch
  MPR121.setReleaseThreshold(4);

このスケッチだと誤動作するので、変数を大きくします。MPR121.setTouchThresholdが15前後、MPR121.setReleaseThresholdが10前後だと問題なく動作するようです。

サンプルスケッチは同じセンサを連続でタップすると、鳴る→止まる→鳴ると動作します。これを鳴る→鳴る→鳴ると動作させるようにしたスケッチを、この記事の最後に置くのでコピーして使って下さい。

スケッチを書き込んだら、Touch BoardにACアダプタとスピーカを接続して完成です。PCのUSBポートだと電流が足りず、誤動作することがあるので、必ずUSB ACアダプター 5V/1.0Aを接続してください。

// touch includes
#include <MPR121.h>
#include <Wire.h>
#define MPR121_ADDR 0x5C
#define MPR121_INT 4

// mp3 includes
#include <SPI.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#include <SFEMP3Shield.h>

// mp3 variables
SFEMP3Shield MP3player;
byte result;
int lastPlayed = 0;

// touch behaviour definitions
#define firstPin 0
#define lastPin 11

// sd card instantiation
SdFat sd;

// define LED_BUILTIN for older versions of Arduino
#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif

void setup() {
  Serial.begin(57600);

  pinMode(LED_BUILTIN, OUTPUT);

  //while (!Serial) ; {} //uncomment when using the serial monitor
  Serial.println("Bare Conductive Touch MP3 player");

  if (!sd.begin(SD_SEL, SPI_HALF_SPEED))  sd.initErrorHalt();

  if (!MPR121.begin(MPR121_ADDR)) Serial.println("error setting up MPR121");
  MPR121.setInterruptPin(MPR121_INT);

  // Changes from Touch MP3
  
  // this is the touch threshold - setting it low makes it more like a proximity trigger
  // default value is 40 for touch
  MPR121.setTouchThreshold(20);
  
  // this is the release threshold - must ALWAYS be smaller than the touch threshold
  // default value is 20 for touch
  MPR121.setReleaseThreshold(10);  

  result = MP3player.begin();
  MP3player.setVolume(10, 10); //right,left

  if (result != 0) {
    Serial.print("Error code: ");
    Serial.print(result);
    Serial.println(" when trying to start MP3 player");
  }

}

void loop() {
  readTouchInputs();
}


void readTouchInputs() {
  if (MPR121.touchStatusChanged()) {

    MPR121.updateTouchData();

    // only make an action if we have one or fewer pins touched
    // ignore multiple touches

    if (MPR121.getNumTouches() <= 1) {
      for (int i = 0; i < 12; i++) { // Check which electrodes were pressed
        if (MPR121.isNewTouch(i)) {

          //pin i was just touched
          Serial.print("pin ");
          Serial.print(i);
          Serial.println(" was just touched");
          digitalWrite(LED_BUILTIN, HIGH);

          if (i <= lastPin && i >= firstPin) {
            if (MP3player.isPlaying()) {
              // if we're already playing the requested track, stop it
              MP3player.stopTrack();
              MP3player.playTrack(i - firstPin);
              Serial.print("a to a repeating track ");
              Serial.println(i - firstPin);
              lastPlayed = i;
            } else {
              MP3player.playTrack(i - firstPin);
              Serial.print("the first playing track ");
              Serial.println(i - firstPin);
              lastPlayed = i;
            }
          }
        } else {
          if (MPR121.isNewRelease(i)) {
            Serial.print("pin ");
            Serial.print(i);
            Serial.println(" is no longer being touched");
            digitalWrite(LED_BUILTIN, LOW);
          }
        }
      }
    }
  }
}