PIC de MIDI

1999年2月 長嶋洋一


PIC de MIDI 99/02/20 23:54


やっと資料がまとまりました_o_
PIC16F84を使ったMIDI小物、その1をお贈りします。

DTM仕様の音源モジュールやキーボード(R社SK-50,Y社CBX-K1XG)をリアル
タイム演奏に使おうとすると音色切替が面倒です。
そこで、ワンタッチで音色番号を選択するために作りました。

1) 数字キー(1-9,0)を押すと、あらかじめ記憶されたProgram#を出力。
2) E を押しながら数字キーを押すと、現在のProgram#がその番号に記憶。
   (EEPROMに記憶されるため、電源を切っても消えません。)
3) C を押すと、Program#=0を出力。
4) ^ を押すと、現在のProgram#に8を加えたProgram#を出力。
5) v を押すと、現在のProgram#から8を引いたProgram#を出力。
6) > を押すと、現在のProgram#に1を加えたProgram#を出力。
7) < を押すと、現在のProgram#から1を引いたProgram#を出力。
(Channel#は1に固定です。)

ではまずハード篇から:
キー・スイッチはジャンク屋で電話用のものを買ってきて、キー・トップを
適当に並べ変えました。
スイッチ・マトリクスを組む場合、同時に押されるスイッチの個数が2個ま
でならばダイオードは不要です。
この回路ではRB0-3を出力、RA1-4を入力にします。
抵抗アレーRA1でプルアップし、ロー・アクティブで動かします。

R1,R2 = 47k RA1 = 8*47k(抵抗アレー) C1,C2 = 22pF Xtal = 2MHz MIDI OUT は規格に準拠すればオープン・コレクタのインバータを使って、 次のような回路になります。(Pwr = +5V)

RB5ではなくオープン・ドレイン出力のRA4を使えば良かったのですが、配線の
楽な方を選んでしまいました。(^_^;)
...ま、ここまでは許してぇ...

さて、電源まで省いて相手の MIDI OUT から電流をもらおうという暴挙も公開
してしまいましょう。(だって、電池もACアダプターも面倒なんだもん。)
短距離で1対1で使う分には一応動きますが、相応のリスクはあるでしょう。
ここで使う三端子レギュレータはMOS型の低ドロップ電圧、超低消費電力のもの
です。(例)リコー RE5RL33A(3.3V)
MIDI端子の4番は、他に電流を横取りしなければフォトカプラーのLED点灯時
でも4V、1mA取られても3.8Vありますから3.3Vに落として使えば安心?です。


などというワガママな製品もあり、要注意です。

ソフト篇に続く...

RE:PIC de MIDI 99/02/21 00:30


PIC小物その1、ソフト篇をお贈りします。
いきなりオープン・ソースにて失礼します。

;Program Memory 1

    LIST    P=PIC16F84
    include	"p16f84.inc"
    LIST    R=DECIMAL
    __config _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC

tx_reg   equ 0x10
tx_lcnt  equ 0x11
tx_wcnt  equ 0x12
out_b    equ 0x13
wcnt1    equ 0x14
wcnt2    equ 0x15
key1_old equ 0x16
key1_new equ 0x17
key2_old equ 0x18
key2_new equ 0x19
key3_old equ 0x1A
key3_new equ 0x1B
key4_old equ 0x1C
key4_new equ 0x1D
key_ent  equ 0x1E
key_tmp  equ 0x1F
pgm_num  equ 0x20
mem_num  equ 0x21
lp_cnt   equ 0x22

    org 0
    goto    start
    retfie
    retfie
    retfie
    retfie
start
    bcf     STATUS,RP0
    movlw   0xFF
    movwf   out_b
    movwf   PORTB

    bsf     STATUS,RP0
    movlw   0xD0
    movwf   TRISB
    movlw   0x7F
    movwf   OPTION_REG

    bcf     STATUS,RP0
    clrf    pgm_num
key_on_loop
    call    key_chk
    bz      key_on_loop
    call    chat_wait
    call    key_chk
    bz      key_on_loop
key_updn
    btfsc   key3_new,1
    call    pgm_up8
    btfsc   key3_new,2
    call    pgm_up1
    btfsc   key4_new,1
    call    pgm_dn8
    btfsc   key4_new,2
    call    pgm_dn1
    btfsc   key4_new,3
    call    pgm_clr
key_mem
    rlf     key2_new,w
    movwf   key_tmp
    rlf     key_tmp
    rlf     key_tmp,w
    andlw   0xF0
    movwf   key_tmp
    rrf     key1_new,w
    andlw   0x0F
    iorwf   key_tmp
    clrf    mem_num
    movlw   8
    movwf   lp_cnt
key_mem_loop
    rrf     key_tmp
    skpnc
    call    pgm_mem
    incf    mem_num
    decfsz  lp_cnt
    goto    key_mem_loop
key_mem9
    btfsc   key3_new,3
    call    pgm_mem
    incf    mem_num
    btfsc   key3_new,4
    call    pgm_mem
key_off_loop
    call    key_chk
    bnz     key_off_loop
    call    chat_wait
    call    key_chk
    bnz     key_off_loop
    goto    key_on_loop

key_chk
key1
    movlw   0xFE
    movwf   out_b
    movwf   PORTB
    movfw   key1_new
    movwf   key1_old
    comf    PORTA,w
    andlw   0x1E
    movwf   key1_new
key2
    movlw   0xFD
    movwf   out_b
    movwf   PORTB
    movfw   key2_new
    movwf   key2_old
    comf    PORTA,w
    andlw   0x1E
    movwf   key2_new
key3
    movlw   0xFB
    movwf   out_b
    movwf   PORTB
    movfw   key3_new
    movwf   key3_old
    comf    PORTA,w
    andlw   0x1E
    movwf   key3_new
key4
    movlw   0xF7
    movwf   out_b
    movwf   PORTB
    movfw   key4_new
    movwf   key4_old
    comf    PORTA,w
    movwf   key_ent
    andlw   0x0E
    movwf   key4_new
key0
    movlw   0xFF
    movwf   out_b
    movwf   PORTB
    movfw   key1_new
    iorwff   key3_new,w
    iorwf   key4_new,w
    return

pgm_up1
    incf    pgm_num,w
    andlw   0x7F
    movwf   pgm_num
    goto    pgm_chng
pgm_up8
    movfw   pgm_num
    addlw   8
    andlw   0x7F
    movwf   pgm_num
    goto    pgm_chng
pgm_dn1
    decf    pgm_num,w
    andlw   0x7F
    movwf   pgm_num
    goto    pgm_chng
pgm_dn8
    movfw   pgm_num
    addlw   -8
    andlw   0x7F
    movwf   pgm_num
    goto    pgm_chng
pgm_clr
    clrf    pgm_num
    goto    pgm_chng
pgm_mem
    movfw   mem_num
    movwf   EEADR
    btfsc   key_ent,4
    goto    pgm_mem_wr
    bsf     STATUS,RP0
    bsf     EECON1,RD
    bcf     STATUS,RP0
    movfw   EEDATA
    movwf   pgm_num
    goto    pgm_chng

pgm_mem_wr
    movfw   pgm_num
    movwf   EEDATA
    bsf     STATUS,RP0
    bsf     EECON1,WREN
    movlw   0x55
    movwf   EECON2
    movlw   0xAA
    movwf   EECON2
    bsf     EECON1,WR
    bcf     EECON1,WREN
    bcf     STATUS,RP0
    return

pgm_chng
    movlw   0xC0
    call    Midi_Out
    movfw   pgm_num
    call    Midi_Out
    return

Midi_Out
    movwf   tx_reg
    bcf     out_b,5     ;start bit
    movfw   out_b
    movwf   PORTB
    call    midi_wait
    nop
    nop
    movlw   8
    movwf   tx_lcnt
midi_loop
    btfsc   tx_reg,0
    bsf     out_b,5
    btfss   tx_reg,0
    bcf     out_b,5
    movfw   out_b
    movwf   PORTB
    call    midi_wait
    rrf     tx_reg
    decfsz  tx_lcnt
    goto    midi_loop
midi_stop_bit
    nop
    nop
    nop
    nop
    bsf     out_b,5     ;stop bit
    movfw   out_b
    movwf   PORTB
    call    midi_wait
    nop
    return

midi_wait
    nop                 ;Xtal=2MHz
    nop
    return

chat_wait
    movlw   8
    movwf   wcnt1
wlp1
    clrf    wcnt2
wlp2
    nop
    nop
    nop
    decfsz  wcnt2
    goto    wlp2
    decfsz  wcnt1
    goto    wlp1
    return

;EEPROM
    org 0x2100
    de    00
    de    16
    de    32
    de    48
    de    56
    de    64
    de    80
    de    96
    de    112
    de    0

    END

その1、終わり。

RE:PIC de MIDI 99/02/21 00:31


やっと資料がまとまりました。
PIC16F84を使ったMIDI小物(今度は大物?)、その2をお贈りします。

さてお待ちかねの光ハープです。
要はキー・スイッチのマトリクスと同じで、スイッチの接点部分をLEDと
フォト・トランジスタに置き換えたものです。
光の絃とNote#との対応はDataEEPROMにテーブルとして持ちます。

ハード篇その1:CPUボード

この回路ではRB0-3を出力、RA0-4を入力にします。
抵抗アレーRA3でプルアップし、ロー・アクティブで動かします。
明るさによるフォト・トランジスタの電流変化をPICのRA0-3に入力するため、
シュミット入力タイプのバス・バッファ HC244を通します。
RB0-3の出力は、どれか1本だけがローになるようにスキャンし、LEDを点灯
させると同時に対応するHC244の出力をアクティブにします。


CN1,2の奇数番ピンはすべてGndに接続。
SW1はプッシュ・オン型。動作テスト、光部の調整に使います。

Pwr= +5V
u1 = 74HC244
u2 = 74HC244
u3 = PIC16F84-10
R1 = 10k
R2 = 10k
RA1= 8*2k2 (2.2k) Pull Up R-Array
RA2= 8*2k2 (2.2k) Pull Up R-Array
RA3= 8*10k  Pull Up R-Array
C1 = 22p
C2 = 22p
Xtal=10MHz

ハード篇その2:光部分

LEDは超高輝度(2000-3000mcd/20mA)で指向角の小さいもの(10度以下)を
使います。2個ずつ直列にすることによって、電流を有効に使います。
フォト・トランジスタは飽和電流2mAのものを使い、プルアップ抵抗RA1,2
(2.2k)による電流ループを作ります。
隣接するLEDからの光の漏れはダイナミック・スキャンによってソフト的に
排除できますが、外部からの光がフォト・トランジスタに当たると誤動作
します_o_

面倒なのは、筐体の木工とLED,PhotoTrの取り付け、光軸合わせです。
光軸合わせは、テスト・モードでLEDを1系統ずつ点灯させ、PhotoTrの
コレクタ側の電圧を測りながら行います。

部品の選別:
LEDもPhotoTrもバラツキがありますから、選別する必要があります。
LEDは樹脂成型なのですがチップの取り付け位置が微妙にズレていて、
光の像はそれぞれ異なります。チップが光軸にぴったり合っている方が、
かえってボンディング点が陰となってしまい、リング状の光が出てしま
います。
PhotoTrは感度(飽和電流)がそれぞれ異なります。



A-A,B-B,...,H-H をそれぞれ接続。

LED GL5UR3K (Sharp)
PhotoTr TPS607A (Toshiba)
R0 = 82[ohm]

ソフト篇に続く...

RE:PIC de MIDI 99/02/21 00:32


光ハープ ソフト篇

;Photo Harp part1
;PentaTonic
;with TestMode

    LIST    P=PIC16F84
    include "p16f84.inc"
    LIST    R=DECIMAL
    __config _CP_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC

note_vel equ 0x10
tx_reg   equ 0x11
tx_lcnt  equ 0x12
tx_wcnt  equ 0x13
out_b    equ 0x14
wcnt1    equ 0x15
wcnt2    equ 0x16
wcnt3    equ 0x17
key1_old equ 0x18
key1_new equ 0x19
key2_old equ 0x1A
key2_new equ 0x1B
key3_old equ 0x1C
key3_new equ 0x1D
key4_old equ 0x1E
key4_new equ 0x1F
key_sw   equ 0x20
key_num  equ 0x21
key_cnt  equ 0x22

    org 0
    goto    start
    retfie
    retfie
    retfie
    retfie
start
    bcf     STATUS,RP0
    movlw   0xFF
    movwf   out_b
    movwf   PORTB

    bsf     STATUS,RP0
    movlw   0xC1
    movwf   TRISB
    bcf     STATUS,RP0

    btfss   PORTA,4
    goto    test_loop

    clrf    key1_old
    clrf    key1_new
    clrf    key2_old
    clrf    key2_new
    clrf    key3_old
    clrf    key3_new
    clrf    key4_old
    movlw   0x01
    movwf   key4_new

loop1
    clrf    key_num
key1
    movlw   0xEF
    movwf   out_b
    movwf   PORTB
    call    wait_on
    movfw   key1_new
    movwf   key1_old
    movfw   PORTA
    movwf   key1_new
    movlw   0xFF
    movwf   out_b
    movwf   PORTB
key1_on
    comf    key1_old,w
    andwf   key1_new,w
    movwf   key_sw
    movlw   64
    movwf   note_vel
    call    key_event
    movlw   4
    subwf   key_num
key1_off
    comf    key1_new,w
    andwf   key1_old,w
    movwf   key_sw
    movlw   0
    movwf   note_vel
    call    key_event
key2
    movlw   0xF7
    movwf   out_b
    movwf   PORTB
    call    wait_on
    movfw   key2_new
    movwf   key2_old
    movfw   PORTA
    movwf   key2_new
    movlw   0xFF
    movwf   out_b
    movwf   PORTB
key2_on
    comf    key2_old,w
    andwf   key2_new,w
    movwf   key_sw
    movlw   64
    movwf   note_vel
    call    key_event
    movlw   4
    subwf   key_num
key2_off
    comf    key2_new,w
    andwf   key2_old,w
    movwf   key_sw
    movlw   0
    movwf   note_vel
    call    key_event
key3
    movlw   0xFB
    movwf   out_b
    movwf   PORTB
    call    wait_on
    movfw   key3_new
    movwf   key3_old
    movfw   PORTA
    movwf   key3_new
    movlw   0xFF
    movwf   out_b
    movwf   PORTB
key3_on
    comf    key3_old,w
    andwf   key3_new,w
    movwf   key_sw
    movlw   64
    movwf   note_vel
    call    key_event
    movlw   4
    subwf   key_num
key3_off
    comf    key3_new,w
    andwf   key3_old,w
    movwf   key_sw
    movlw   0
    movwf   note_vel
    call    key_event
key4
    movlw   0xFD
    movwf   out_b
    movwf   PORTB
    call    wait_on
    movfw   key4_new
    movwf   key4_old
    movfw   PORTA
    movwf   key4_new
    movlw   0xFF
    movwf   out_b
    movwf   PORTB
key4_on
    comf    key4_old,w
    andwf   key4_new,w
    movwf   key_sw
    movlw   64
    movwf   note_vel
    call    key_event
    movlw   4
    subwf   key_num
key4_off
    comf    key4_new,w
    andwf   key4_old,w
    movwf   key_sw
    movlw   0
    movwf   note_vel
    call    key_event
    goto    loop1

key_event
    movlw   4
    movwf   key_cnt
key_loop
    btfsc   key_sw,3
    call    note_event
    rlf     key_sw
    incf    key_num
    decfsz  key_cnt
    goto    key_loop
    return

note_event
    movlw   0x90
    call    Midi_Out
    movfw   key_num
    movwf   EEADR
    bsf     STATUS,RP0
    bsf     EECON1,RD
    bcf     STATUS,RP0
    movfw   EEDATA
    call    Midi_Out
    movfw   note_vel
    call    Midi_Out
    return

Midi_Out
    movwf   tx_reg
    bcf     out_b,5     ;start bit
    movfw   out_b
    movwf   PORTB
    call    midi_wait
    nop
    nop
    movlw   8
    movwf   tx_lcnt
midi_loop
    btfsc   tx_reg,0
    bsf     out_b,5
    btfss   tx_reg,0
    bcf     out_b,5
    movfw   out_b
    movwf   PORTB
    call    midi_wait
    rrf     tx_reg
    decfsz  tx_lcnt
    goto    midi_loop
midi_stop_bit
    nop
    nop
    nop
    nop
    bsf     out_b,5     ;stop bit
    movfw   out_b
    movwf   PORTB
    call    midi_wait
    nop
    return

midi_wait               ;Xtal=10MHz
    nop
    nop
    movlw   21
    movwf   tx_wcnt
midi_wait_loop
    decfsz  tx_wcnt
    goto    midi_wait_loop
    return

wait_on
    movlw   10
    movwf   wcnt1
wlp1
    clrf    wcnt2
wlp2
    nop
    nop
    decfsz  wcnt2
    goto    wlp2
    decfsz  wcnt1
    goto    wlp1
    return

;Photo Harp part2
;test mode

test_loop
    movlw   0xEF
    movwf   PORTB
    call    kwait
    movlw   0xF7
    movwf   PORTB
    call    kwait
    movlw   0xFB
    movwf   PORTB
    call    kwait
    movlw   0xFD
    movwf   PORTB
    call    kwait
    goto    test_loop

kwait
kwait_hi
    btfss   PORTA,4
    goto    kwait_hi
kwait_lo
    btfsc   PORTA,4
    goto    kwait_lo
    movlw   100
    movwf   wcnt1
kwlp1
    clrf    wcnt2
kwlp2
    nop
    nop
    decfsz  wcnt2
    goto    kwlp2
    decfsz  wcnt1
    goto    kwlp1
    btfsc   PORTA,4
    goto    kwait_lo
    return

    org 0x2100
;EEPROM    Note#    PhotoTr
    de      50      ; 1
    de      60      ; 5
    de      69      ; 9
    de      79      ;13
    de      52      ; 2
    de      62      ; 6
    de      71      ;10
    de      81      ;14
    de      55      ; 3
    de      64      ; 7
    de      74      ;11
    de      83      ;15
    de      57      ; 4
    de      67      ; 8
    de      76      ;12
    de      85      ;16

    END