Techno Toys Laboratory

連載第6回 今月のお題「デューパールーパ 試作編」


当研究所はいよいよ3つ目のアイテムの製作に入る。今回はドラムマシンの研究だ。とは言ってももちろんただのドラムマシンではなくて、実際にモノを叩く機械式のリズムシーケンサを開発してみた。今回はプロトタイプ編デス。

ヒントはトイレから?

 トイレのドアをノックした経験はだれにでもあると思うけど、あれってなんかデジタル通信っぽくない?半2重シリアル通信そのものじゃないかと思うんだけど。
 まあ、それはおいといて、今回の製作のヒントはまさにトイレのノックから得たものなんだ。公衆トイレで順番待ちしながら、「ドアの内側に、ノックの音を検出して同じ音のパターンを真似て返事するような装置をつけたら、だれも入れなくて面白いなぁ」なんてことを考えついたのだが、えてして製作のネタというものはこんな風に日常に転がっているわけです。


《第1図》最初に思い浮かんだ装置
いつまでもノックを返すトイレの構想…
今回製作する装置も仕組みはまったく同じだ
 で、早速その装置のブロック図を書いてみると第1図のようになる。仕組みはシンプルで、ノック音を検出するセンサとノックをするためのアクチュエータ、それから検出した音のパターンを遅らせて返事らしいタイミングをとるためのメモリで構成される。書いてみて気が付いたことは、装置のノックの出力が自分の入力にフィードバックされた場合、こいつは同じパターンを延々と叩き続けるのではないかということだ。これってドラムマシンになるかも?と気づいたのだが、えてして製作はこんな風に思わぬ方向にズレていくのだった。

デューパールーパの使い方

 こうして構想に至った反復型ドラムマシンはデューパールーパと名付けられた。打音を複製(デュープ)して反復(ループ)することに由来している。システム構成はトイレのイタズラ装置と全く一緒で、衝撃センサからの入力をディレイしてソレノイド(電磁石により往復運動をするアクチュエータ)から出力する。写真1が製作したデューパールーパのプロトタイプだ。電源、回路、センサ、ソレノイドによるドラム・スティックのメカから成り立っている。

 使い方は以下のようになる。第2図はそのイメージだ。


《第2図》デューパールーパの使い方
  1. 本機を何か叩かれる部材に取り付ける。ドア、床、箱など音がするものなら何でも可。
  2. プレーヤが本機を取り付けた部材を叩いて音をだす。
  3. 叩いた衝撃は部材を伝わり、センサがそれを検出してメモリに蓄える。
  4. 1小節後、本機が同じリズムで部材を叩きだす。
  5. プレーヤはそれを聴きながら打音を追加することが出来る。
  6. スティックを手でおさえることで記憶された打音を消去できる。
 文章で書くと複雑めいてしまうけど、実際にはとても簡単かつ直感的な操作で演奏できる。プレーヤは部材を叩くか、デューパールーパのスティックを手でおさえるだけ。ちなみにこのような、ディレイのかかった音にさらに音を重ねる演奏方法はサウンド・オン・サウンドと呼ばれる。

回路図

 デューパールーパの試作回路図と実体配線図が第3図、第4図。それから第1表がパーツリストだ。これは試作版なので、次回完成編で若干の部品の追加をするけど、大きな変更は無いので安心して組み立てを開始していただきたい。


《第3図》デューパールーパの試作回路図
図中の↑はともに電池に接続する


《第4図》デューパールーパの実体配線図
取り付け方向がある部品には特に注意してハンダ付けしよう

ユニバーサル基板45mmx45mm程度のものを切って使用x 1
電池ボックス単3乾電池4本用x 1
ICソケット18ピンx 1
PIC16F84x 1
セラロック10MHz
x 1
トランジスタ2SC1815x 1
2SC3420x 1
ダイオード10E1x 1
ショットキ・バリア・ダイオード11EQS04x 1
抵抗100Ωx 1
220Ωx 1
100kΩx 1
1MΩx 1
半固定抵抗500kΩx 1
積層セラミックコンデンサ0.1μFx 1
電解コンデンサ1000μF 16Vx 1
圧電素子x 1
ソレノイドMD-232-1 (6V用)x 1
その他、プラ版やバネなど
《第1表》デューパールーパのパーツリスト
ソレノイドは似たようなものでも良いけど、なるべくストロークの大きいものがよさそうだ。

 センサは以前も使った圧電素子をつかう。圧電素子は電圧を加えると音が出るのでブザーとしても使えるが、逆に振動を与えると電圧を発生する(第5図)。今回は後者のようにセンサとして使う。打音を音として検出すると色んな音に反応してしまうので、叩く部材の振動を直接拾うようにする。
 トランジスタで圧電素子の微弱な出力電圧を増幅し、PIC(今回もPIC16F84を使います)の入力ピンに入力する。その際、感度調整を半固定抵抗で行う。
 増幅回路の関係で信号の高低は、普段はHi(高い電圧)で衝撃を検出するとLo(0V)になる。


《第5図》圧電素子の働き
圧電素子は電気信号を加えると音を発生する。
逆に、振動を与えると、電圧を発生する。

 部材を叩いて音を出すには電気信号を機械運動に変える必要がある。そのために使うのがソレノイドだ。ソレノイドは電磁石と鉄芯からなり、電流を流すと鉄芯が吸い寄せられて往復運動を作り出す(第6図)。スティックでものを叩かせるには、後で説明するように、この往復運動を機構を作ってスティックの回転運動に変換すればよい。


《第6図》ソレノイドの働き
ソレノイドは電流を運動に変える部品だ
電流を流すと鉄芯が吸い寄せられ、往復運動が生まれる
 ソレノイドが動くためにはとても大きな電流を流す必要がある。PICでは直接ドライブできないので、ここにもトランジスタを使う。ソレノイドの両端につけられたダイオードは電磁石に発生する逆起電力からトランジスタを守るためのものだ。

 ソレノイドはとても大きな電流を消費するので、電源に注意が必要になる。電磁石がONになると、電池の容量の関係で電源電圧が落ちてしまう。これはPICの誤動作につながるので、ダイオードとコンデンサでそれを防ぐ。なお、電池はアルカリ乾電池を使ったほうが無難だ。

スティック部の組み立て

 ソレノイドの往復運動をスティックの回転運動に変える機構はまさに工作の世界。ここはプラ板とプラ棒を切って製作した。この部分の完成形の図面は次回に掲載したいと思う。というのも、この部分の設計次第で音のシャープさが決まってくるようなので、実はいろいろと試行錯誤中なんですな。参考までにおおよその作り方を第7図に示すけど、ここは各自工夫してみて欲しいところ。機構の寸法、バネの強さやスティックの作りに至るまで、ひとつひとつのちょっとした違いが動作に影響してくる。意外と奥が深いところなのだ。
 とはいってもセンサが反応するだけの音を出すのはそれほど難しいことではないので、ありあわせの材料でまずはやってみて。


《第7図》スティックの機構(参考)
ソレノイドと黒丸の部分はシャーシに固定する
適切な寸法は入手したバネの強さによっても変わってくるので注意

プログラムの概要

 第8図がテストプログラムのフローチャート、リスト1がそのソースリストだ。PICに書き込む時は、HSモード、パワー・アップ・タイマ使用、ウォッチドッグ不使用と指定してください。プログラム的にはたいしたことはやっていないけど、特に気を使った点を説明しておこう。
   ドラムマシンである以上、時間の管理がトテモ大事なのはいうまでもない。タイマ割り込みによって一定時間を測り、フラグを通じてメインルーチンへ処理のタイミングを知らせる作りになっている。



《第8図》テスト・プログラムのフローチャート
プログラム自体はいたってシンプルだ
;========================================================================
;
;                        d u p e r   l o o p e r
;
;                   c o d e d  b y  ク ワ ク ホ ゙ リ ョ ウ タ
;
;========================================================================
;
        LIST    C=120, p=16F84, r=dec, x=off, n=0
        include 

;======== マクロの定義 ==================================================
push    macro
        movwf   w_temp
        swapf   STATUS,W
        bcf     STATUS,RP0
        movwf   status_temp
        endm

pop     macro
        swapf   status_temp,W
        movwf   STATUS
        swapf   w_temp,F
        swapf   w_temp,W
        endm

;======== シンボルの定義 ================================================
;-------- レジスタ名の定義 --------
temp                    equ     0x0c    
w_temp                  equ     0x0d    ; 割り込み時のレジスタ退避用
status_temp             equ     0x0e    ;             //
count0                  equ     0x0f    ; タイミング用カウンタ
event                   equ     0x10    ; イベントフラグ
stat                    equ     0x11    ; ステータスフラグ
step                    equ     0x12    ; リズムのステップカウンタ
rhythm_buf              equ     0x13    ; リズム用バッファ (STEP_MAX/8 byte)

;-------- 各変数の初期値 --------
COUNT0_INIT             equ     130     ; 140BPMにリズムを決める
STEP_MAX                equ     16      ; 16ステップで1ループ

;-------- eventのビットマップ --------
TRIG                    equ     0       ;

;-------- statのビットマップ --------
HALF                    equ     0       ;

;-------- PORTAのビットマップ --------
DRIVE_PIN               equ     0

;======== リセットベクタ ===============================================
        org     0x0000                  ; 起動時は0番地から実行を始める
        goto    initialize

;======== 割り込みベクタ ===============================================
        org     0x0004                  ; 割り込みが起きると
                                        ;           4番地にジャンプする
;======== 割り込みルーチン ============================================
interrupt:
        push                            ; コンテキストの保存
        
        decfsz  count0,F                ; count0--==0なら以下を実行
        goto    int_90                  ; それ以外は90へ
        
        movlw   COUNT0_INIT             ; count0の初期化
        movwf   count0                  ;
        
        bsf     event,TRIG              ; TRIGフラグをセット
        
        movlw   1<>3
                                        ; temp <- stepの下位3ビット

        btfss   INTCON,RBIF             ; 入力に変化あり?
        goto    first_half_10           ;       なければ10へ

        movf    temp,W                  ; リズムパターンに音符を書き込む
        iorwf   INDF,F                  ;
        goto    first_half_20           ;

first_half_10:
        comf    temp,W                  ; リズムパターンに休符を書き込む
        andwf   INDF,F                  ;
        goto    first_half_20           ;

first_half_20:
        movf    PORTB,F                 ; RBIFのリセット
        bcf     INTCON,RBIF             ;

        incf    step,F                  ; stepの更新
        movf    step,W                  ; (0〜STEP_MAXを繰り返す)
        sublw   STEP_MAX                ;
        btfsc   STATUS,Z                ;
        clrf    step                    ;

        return                          ;
        
;========================================================================
second_half:
        call    select_memory           ; FSR  <- step>>3
                                        ; temp <- stepの下位3ビット
        
        movf    INDF,W                  ; 音符があったらソレノイドをONに
        andwf   temp,W                  ;
        btfss   STATUS,Z                ;
        bsf     PORTA,DRIVE_PIN         ;
        
        return                          ;
        
;========================================================================
; サブルーチン : select_memory
;           stepの値に応じてアクセスするメモリのアドレスと、ビット位置を設定する
;           FSR  <- step >> 3
;           temp <- 3 least bit of step
;========================================================================
select_memory:
        rrf     step,W                  ; 現在のstepに対応する
        movwf   temp                    ; 音符が格納されているアドレスを算出
        rrf     temp,F                  ; (FSR <- step >> 3)
        rrf     temp,W                  ;
        andlw   b'00011111'             ;
        addlw   rhythm_buf              ;
        movwf   FSR                     ;
        
        movf    step,W                  ; 現在のstepに対応する
        andlw   b'00000111'             ; 音符が格納されているビット位置
        call    bit_table               ; (temp <- stepの下位3ビット)
        movwf   temp                    ;
        
        return
        
bit_table:                              ; 0〜7の数値を
        addwf   PCL,F                   ;      ビット位置に変換するテーブル
        retlw   1<<7                    ;
        retlw   1<<6                    ;
        retlw   1<<5                    ;
        retlw   1<<4                    ;
        retlw   1<<3                    ;
        retlw   1<<2                    ;
        retlw   1<<1                    ;
        retlw   1<<0                    ;
        
;========================================================================
        end
《リスト1》デューパールーパのテスト・プログラム
ダウンロード

 記憶するリズムパターンは16ステップで一回りするように設定した。リズムパターンのメモリ管理は第9図のようになっている。


《第9図》リズムの記録方法
16ステップのリズム・パターンを2バイトに収納している
 一定時間毎に参照するステップをひとつずつずらしながら、音符があるときはソレノイドを動かし、休符のときは動かさない。一方で、各ステップ毎に衝撃センサからの入力があったかどうかを調べ、入力があった場合は現在の参照ステップに音符を書き込み、入力が無かった場合は休符を書き込む。これを繰り返す。本機がソレノイドの運動によって部材を叩くと、その衝撃が自分自身のセンサに入力されるから、結果的に同一パターンがループしていくことになる。また、ソレノイドの動きを強制的に手で止めると、センサ入力はなくなるから、休符が書き込まれる。このことにより、ループするリズムパターンから任意の音符を取り除くことが出来る。

 そのプロセスを詳しく示したタイミング・チャートが第10図だ。各ステップ時間の最後にセンサ入力があったかどうかを調べ、リズムパターンのメモリに結果を書き込む。従って、プレーヤの打音のタイミングが多少ばらついていても、このステップ時間内に収まっていれば、ジャストのタイミングと同じ扱いになる。16ステップのループを4拍子1小節と考えると、どんなリズムも16分音符単位に直されることになる。このようなテクニックは、コンピュータ・ミュージックの世界では「クォンタイズ(量子化)」と呼ばれる。
 ソレノイドの動作開始は各ステップ時間の真ん中で行っている。プレーヤは本機の叩くリズムを聞きながら音を重ねていくのだけど、プレーヤの叩くタイミングが前にずれても後ろにずれても同一のステップに収まるようにするためだ。こうした方が誤入力が少なくなる。


《第10図》タイミング・チャート
一定時間毎に2種類(リズムパターンの更新とソレノイドの動作)の処理を交互にくり返している

 それから、クォンタイズするのにはもうひとつ理由がある。ソレノイドが電気的にONになってから、スティックが部材を叩く瞬間までには多少の遅れがある。ステップの分解能が高いと、この遅れの影響でリズムパターンがどんどん狂ってしまう。クォンタイズによって、遅れがキャンセルされるので、リズムパターンは一定に保たれる。
 そんなわけで、実際には半ステップごとに割り込みルーチンがTRIGフラグをたてて、センサのチェックとリズムパターンの更新(前半処理と表記した)と、リズムパターンのチェックとソレノイドの動作(後半処理と表記した)を交互に行っている。

センサ入力の調べ方

 センサ入力の検出方法について説明しておこう。圧電素子の電圧はトランジスタによって増幅され、普段はHi、衝撃入力時にLoになる。この信号はRB7ピンに接続されている。PIC16F84はRB4〜RB7のどれかの入力電圧が変化した時にINTCONレジスタのRBIFフラグをセットする。この機能は「ある期間内に少なくとも1回入力が変化した」ことを検出するのに便利だ。使い方は以下の通り。
  1. PORTBを読む(または書く)
  2. INTCONレジスタのRBIFフラグをリセットする
  3. 必要になったらRBIFフラグを調べる
  4. 1,2が検出の初期化で、RBIFフラグのリセットの前に一度PORTBにアクセスしておくことをお忘れなく。このアクセス時の値と入力を比較して変化を検出するからだ。
  5. この機能を使えば、リアルタイムに入力を見張っている必要がない。ちなみにこのフラグは割り込みも起こすことが出来る。

さて動作は?

 試作機が完成したら早速動作をチェックしてみよう。
 机などの表面にスティック部、センサ部をテープで軽く固定して電源をON。この時点では何も起きないのが正解。では机を小突いてみよう。ワンテンポおいてスティックが同じリズムで動き出すはずだ。動かない時や、余計な入力を拾って暴れだすような場合は基板の半固定抵抗を回して感度を調節しよう。スティックが等間隔で同じパターンを繰り返すようになったら成功! やってみると、叩く部材は金属の缶などよりも木の板のように残響音の少ないものの方が上手くいくようだ。残響があまり長いと、次のステップにまで音がコピーされてしまい、しまいには16連打状態になってしまう。

 テンポは140BPMに設定してある。リスト中の定数を変更すれば、テンポやステップ数などを変えることもできる。いろいろいじってみて。

 次回はスティック機構の完成形と、幾つかの機能の追加、そして仕上げ、応用例などを紹介したいと思ってます。乞うご期待!



《写真1》デューパールーパ試作機
センサとスティックの位置関係によって動作の具合も変わってくる。はやくパッケージしたいところだ

【参考文献】 (1)山名宏治(著);作りながら学ぶロボット工作入門5、トランジスタ技術(刊)、2001年5月号、pp.155〜160、CQ出版(株)