センサ→MIDIインターフェースキーエンスの赤外線センサは、反射板までの赤外線ビームを遮断 する状態をON/OFFとしてリレー出力(スイッチのようなもの)しています。 そこで、この7個のスイッチ状態をMIDI化してMAXに送る インターフェースを作りました。
![]() センサ部分は、オブジェとして制作して、展示会場ではケーブルで かなり長く伸ばすので、延長コードとしてRCAのピンケーブルを使用 することにしました。また、教育的な意図から、敢えてケースに入れずに 基板ムキ出しにして中身が見えるようにしました。そこで全体としては、 このように、8個のピンジャックとマイコン基板の並ぶ外見となりました。
![]() 使ったのは、いつも使い慣れた(^_^)、秋月電子のAKI-H8です。
![]() 回路図は例によって、まったく描かずにいきなり穴あけとハンダ付けを 開始しました。これは、あとから思い出して描いた回路図です。 いい子は真似しないように。(^_^;)
![]() ケースの裏側はこんな感じで、電源モジュールとMIDI出力バッファが あります。この電源は、秋月電子の店頭に積んでいた極安品。
![]() MIDI出力は、ちゃんと74HC05で送っています。
![]() 何も見ないで、ここまでの制作に3時間ぐらいかかりました。そして、 あとはいよいよAKI-H8のソフトだけだ、という楽しい作業を残して 帰ろうとしたのですが、第1期虎の穴の加藤さんが、AKIのプログラミングを 見てみたい、というので、そのまま続けてソフト開発に進みました。 考えてみると、これまでのMIDIオリジナル機器は全てASLの実験室(自室)で 一人で黙々と開発してきたので、加藤さんは、「AKIものの誕生に立会った 最初の人」ということになりました。(^_^)
AKI-H8の開発環境とか開発手順とかは、 こちら にあるので詳細は省略します。PowerBookでVirtualPCを走らせて、 そこにWindows95を走らせてその中でDOS窓を開きます。 ソースプログラムは秀丸エディタで編集し、あとは秋月のツール でアセンブル、リンク、そしてフラッシュROMに書き込む、という ループを回すだけです。
![]() DOS窓の中で開発用に使ったオリジナルのバッチプログラム は以下のようなものです。 a38h %1.src -cpu=300ha:20 l38h %1.obj -output=FlashROM.abs c38h FlashROM pause del FlashROM.abs del %1.obj del %1.lis flash 今回のAKI-H8のソースプログラムは以下のようなものです。 ちょっと詳しい解説をしている余裕がないので、省略です。 虎の穴には機会をみて、おいおい伝授していきましょう。(^_^;) ;----------------------------------------------------------- ; ; Shinkai : May 2000 ; ;----------------------------------------------------------- ;##### Port Defines ##### smr .equ h'0fffb0 brr .equ h'0fffb1 scr .equ h'0fffb2 tdr .equ h'0fffb3 ssr .equ h'0fffb4 rdr .equ h'0fffb5 paddr .equ h'0fffd1 padr .equ h'0fffd3 pbddr .equ h'0fffd4 pbdr .equ h'0fffd6 iprb .equ h'0ffff8 ;##### Vector Defines ##### .section vector,data,locate=h'000000 .data.l start ;##### Work RAM Data Defines ##### .section ram,data,locate=h'0fef10 timer1 .res.w 1 timer2 .res.w 1 tx_top .res.w 1 tx_end .res.w 1 counter .res.b 1 led .res.b 1 ad_data .res.b 1 old_sw .res.b 1 timer3 .res.b 1 .org h'0ff400 tx_fifo .res.b 1024 ;***** Reset --> Initialize --> Main Loop ***** .section program,code,locate=h'002000 start: mov.l #h'0fff0f,er7 ; stack pointer set mov.l #h'0fef10,er2 mov.w #h'0fe0,r1 mov.b #0,r0l _ram_clear: mov.b r0l,@er2 inc.l #1,er2 dec.w #1,r1 bne _ram_clear jsr @sci0_init ; SCI initialize mov.b #b'00000000,r0l mov.b r0l,@paddr ; set : Port[A] all input mov.b #b'11111111,r0l mov.b r0l,@pbddr ; set : Port[B] all output mov.b #b'01110000,r0l ; tx/rx start ! mov.b r0l,@scr mov.b #0,r0l mov.b r0l,@pbdr loop: jsr @ad_check jsr @timer_check jsr @tx_midi_check jmp @loop ;***** A/D Check Routine ***** ad_check: mov.b @timer3,r1l inc.b r1l mov.b r1l,@timer3 cmp.b #100,r1l beq _ad_1 rts _ad_1: mov.b #0,r1l mov.b r1l,@timer3 jsr @sw_check rts sw_check: mov.b @padr,r2l mov.b @old_sw,r2h cmp.b r2l,r2h bne _sw_event rts _sw_event: btst #0,r2l beq _sw002 ; new=ON btst #0,r2h bne _sw002 ; old=OFF --> pass mov.b #h'90,r0h jsr @tx_fifo_set mov.b #60,r0h jsr @tx_fifo_set mov.b #100,r0h jsr @tx_fifo_set mov.b #60,r0h jsr @tx_fifo_set mov.b #0,r0h jsr @tx_fifo_set _sw002: btst #1,r2l beq _sw102 ; new=ON btst #1,r2h bne _sw102 ; old=OFF --> pass mov.b #h'90,r0h jsr @tx_fifo_set mov.b #62,r0h jsr @tx_fifo_set mov.b #100,r0h jsr @tx_fifo_set mov.b #62,r0h jsr @tx_fifo_set mov.b #0,r0h jsr @tx_fifo_set _sw102: ; jmp @exit_point btst #2,r2l beq _sw202 ; new=ON btst #2,r2h bne _sw202 ; old=OFF --> pass mov.b #h'90,r0h jsr @tx_fifo_set mov.b #64,r0h jsr @tx_fifo_set mov.b #100,r0h jsr @tx_fifo_set mov.b #64,r0h jsr @tx_fifo_set mov.b #0,r0h jsr @tx_fifo_set _sw202: btst #3,r2l beq _sw302 ; new=ON btst #3,r2h bne _sw302 ; old=OFF --> pass mov.b #h'90,r0h jsr @tx_fifo_set mov.b #65,r0h jsr @tx_fifo_set mov.b #100,r0h jsr @tx_fifo_set mov.b #65,r0h jsr @tx_fifo_set mov.b #0,r0h jsr @tx_fifo_set _sw302: btst #4,r2l beq _sw402 ; new=ON btst #4,r2h bne _sw402 ; old=OFF --> pass mov.b #h'90,r0h jsr @tx_fifo_set mov.b #67,r0h jsr @tx_fifo_set mov.b #100,r0h jsr @tx_fifo_set mov.b #67,r0h jsr @tx_fifo_set mov.b #0,r0h jsr @tx_fifo_set _sw402: btst #5,r2l beq _sw502 ; new=ON btst #5,r2h bne _sw502 ; old=OFF --> pass mov.b #h'90,r0h jsr @tx_fifo_set mov.b #69,r0h jsr @tx_fifo_set mov.b #100,r0h jsr @tx_fifo_set mov.b #69,r0h jsr @tx_fifo_set mov.b #0,r0h jsr @tx_fifo_set _sw502: btst #6,r2l beq _sw602 ; new=ON btst #6,r2h bne _sw602 ; old=OFF --> pass mov.b #h'90,r0h jsr @tx_fifo_set mov.b #71,r0h jsr @tx_fifo_set mov.b #100,r0h jsr @tx_fifo_set mov.b #71,r0h jsr @tx_fifo_set mov.b #0,r0h jsr @tx_fifo_set _sw602: btst #7,r2l beq _sw702 ; new=ON btst #7,r2h bne _sw702 ; old=OFF --> pass mov.b #h'90,r0h jsr @tx_fifo_set mov.b #72,r0h jsr @tx_fifo_set mov.b #100,r0h jsr @tx_fifo_set mov.b #72,r0h jsr @tx_fifo_set mov.b #0,r0h jsr @tx_fifo_set _sw702: exit_point: mov.b r2l,@old_sw rts ;***** SCI init / MIDI Transmit Routines ***** sci0_init: mov.b #b'00000000,r0l mov.b r0l,@scr mov.b #b'00000000,r0l mov.b r0l,@smr mov.b #15,r0l mov.b r0l,@brr mov.w #500,r0 _sci0_wait: dec.w #1,r0 bne _sci0_wait mov.b @ssr,r0l ; (dummy read) mov.b #0,r0l mov.b r0l,@ssr mov.b #b'00001000,r0l mov.b r0l,@iprb ; SCI0-int priority UP ! rts tx_midi_check: mov.w @tx_top,r1 mov.w @tx_end,r6 cmp.w r1,r6 bne _tx_exist rts _tx_exist: btst #7,@ssr ; test TRDE bne _tx_seq rts _tx_seq: mov.w #0,e6 mov.b @(tx_fifo,er6),r0l mov.b r0l,@tdr bclr #7,@ssr ; Transmit ! inc.w #1,r6 bclr #2,r6h mov.w r6,@tx_end rts tx_fifo_set: mov.w @tx_top,r6 mov.w #0,e6 mov.b r0h,@(tx_fifo,er6) ; transmit data = [r0h] inc.w #1,r6 bclr #2,r6h mov.w r6,@tx_top rts ;***** Timer / Counter Routines ***** wait_500msec: mov.l #500,er1 _wait_1: jsr @wait_1msec sub.l #1,er1 bne _wait_1 rts wait_1msec: mov.l #2048,er2 _wait_2: sub.l #1,er2 bne _wait_2 rts timer_check: mov.w @timer1,r1 inc.w #1,r1 mov.w r1,@timer1 beq _timer_1 rts _timer_1: mov.w @timer2,r1 inc.w #1,r1 mov.w r1,@timer2 cmp.w #128,r1 bne _timer_2 mov.w #0,r1 mov.w r1,@timer2 _timer_2: mov.b @led,r0l bnot #5,r0l mov.b r0l,@led mov.b r0l,@pbdr ; write to Port[B] rts .end AKI-H8のフラッシュROMに送ったモトローラ形式の オブジェクトは以下のようなものです。これだけあれば、 同一の回路についてはアセンブル不要で走ります。 S00E0000466C617368524F4D4D4F5426 S107000000002000D9 S11320007A07000FFF0F7A02000FEF1079010FE03C S1132010F80068A80B721B5146F85E0021C0F80057 S113202038D1F8FF38D4F87038B2F80038D65E00EB S1132030203E5E0022545E0021E05A00202E6A09F1 S1132040EF1C0A096A89EF1CA964587000025470D6 S1132050F9006A89EF1C5E00205C54702AD36A027F S1132060EF1B1CA2586000025470730A58700024BE S113207073025860001EF0905E002216F03C5E0072 S11320802216F0645E002216F03C5E002216F00079 S11320905E002216731A5870002473125860001ED3 S11320A0F0905E002216F03E5E002216F0645E00A1 S11320B02216F03E5E002216F0005E002216732AFE S11320C05870002473225860001EF0905E002216A0 S11320D0F0405E002216F0645E002216F0405E00BF S11320E02216F0005E002216733A587000247332F1 S10920F05860001EF09091 S11320F65E002216F0415E002216F0645E00221690 S1132106F0415E002216F0005E002216734A5870F4 S1132116002473425860001EF0905E002216F043BE S11321265E002216F0645E002216F0435E0022165D S1132136F0005E002216735A5870002473525860DA S1132146001EF0905E002216F0455E002216F06433 S11321565E002216F0455E002216F0005E0022168F S1132166736A5870002473625860001EF0905E0014 S11321762216F0475E002216F0645E002216F04730 S11321865E002216F0005E002216737A5870002451 S113219673725860001EF0905E002216F0485E00CF S11321A62216F0645E002216F0485E002216F00046 S11321B65E0022166A8AEF1B5470F80038B2F800E4 S11321C638B0F80F38B1790001F41B5046FC28B437 S11321D6F80038B4F80838F854706B01EF146B063E S10721E6EF161D16BA S11321EA5860000254707EB47370586000025470D1 S11321FA790E000078606A28000FF40038B37FB4C0 S113220A72700B5672266B86EF1654706B06EF14B8 S113221A790E000078606AA0000FF4000B5672264C S113222A6B86EF1454707A01000001F45E002244B5 S113223A7A310000000146F454707A020000080063 S113224A7A320000000146F854706B01EF100B510B S113225A6B81EF105870000254706B01EF120B512F S113226A6B81EF1279210080586000087901000020 S113227A6B81EF126A08EF1971586A88EF1938D619 S105228A54708B S9032000DD あまり美しくない単純なコピーですが、人体が赤外線を遮断する というセンシングには、これでも十分なものでした。 途中、間抜けなミスに10分ほど悩むところを加藤さんにしっかり 目撃されましたが(^_^;)、基本的にはハードの配線からソフトまで ほぼノーバグで無事に完成しました。(^_^)
|