LoginSignup
0
0

More than 5 years have passed since last update.

[森のタクト] 各スピーカーを個別にONOFFするためのハードウェアボタンの作成する

Last updated at Posted at 2016-08-05

Maker Faire Tokyo 2016 森のタクトについての詳細記事です。

概要

手元のハードウェアボタンを押すと、それに対応したスピーカーをミュートにしたり、再びミュートを解除したりという機能を実装していますが、ここではこの機能について説明します。今回5つのボタンを用意しました。

IMG_9060.jpg

詳細

LED付きボタン回路の作成

ただの、タクトスイッチを使用してもよいのですがそれだと今Muteなのか、Mute解除なのかが視覚的にわかりにくいのでLED付きボタンを使うことにしました。
回路図が2枚になっているのは、1枚目の基板は極力ボタン以外の部品は載せず、2枚目の基板はそれ以外の部品を載せ、2枚を積み重ねる構成にしているためです。

回路は、ローパスフィルタとシュミットトリガでチャタリング回避、フリップフロップで状態の保持などを行っています。フリップフロップの出力はは外に引き出してクライアント(RaspberryPi)への入力になります。

回路その1

スクリーンショット 2016-08-05 11.20.47.png

回路その2

SWx_AとSWx_Bという信号は実際はショートされています。
スクリーンショット 2016-08-05 11.17.34.png

ボタンからの入力に応じて音をMuteにする

上記回路からの5つのInputに対して割り込みを設定とハンドラーを追加します。
あとは、GPIOの状態をslave_en_flagとして保持し、note_onイベントのvelocityにかけるようにします。
そうするともしインプットがLowの場合はflagが0になっているので、velocityも0になりMuteになります。


unsigned char slave_en_flags[6] = {1, 1, 1, 1, 1, 1};

void sw1_event(){
    slave_en_flags[0] = digitalRead(BCM_SW1);
    printf("Detect SW1 Event: %d");
}

void sw2_event(){
    slave_en_flags[1] = digitalRead(BCM_SW2);
    printf("Detect SW2 Event: %d");
}

void sw3_event(){
    slave_en_flags[2] = digitalRead(BCM_SW3);
    printf("Detect SW3 Event: %d");
}

void sw4_event(){
    slave_en_flags[3] = digitalRead(BCM_SW4);
    printf("Detect SW4 Event: %d");
}

void sw5_event(){
    slave_en_flags[4] = digitalRead(BCM_SW5);
    printf("Detect SW5 Event: %d");
}

int main(){
    //省略

    wiringPiISR(BCM_SW1, INT_EDGE_BOTH, sw1_event);
    wiringPiISR(BCM_SW2, INT_EDGE_BOTH, sw2_event);
    wiringPiISR(BCM_SW3, INT_EDGE_BOTH, sw3_event);
    wiringPiISR(BCM_SW4, INT_EDGE_BOTH, sw4_event);
    wiringPiISR(BCM_SW5, INT_EDGE_BOTH, sw5_event);

    //省略

    //再生
    for(p = datahead->next; p != NULL; p = p->next){

        switch(0xf0 & p->sendbuf[0]){
            case 0xc0:
                //program Change
                pgm_change(slave_num, 0x0f & p->sendbuf[0], p->sendbuf[1]);

                break;
            case 0x80:
                //note off
                note_off(slave_num, 0x0f & p->sendbuf[0], p->sendbuf[1], p->sendbuf[2]);

                break;
            case 0x90:
                //note on
                note_on(slave_num, 0x0f & p->sendbuf[0], p->sendbuf[1], p->sendbuf[2]*slave_en_flags[slave_num]);

                break;
            default:
                //printf("Other events\n");
                break;
        }

        usleep(p->wait_time * coeff);

    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0