since 2006 ~ 2013
自作電子楽器ノブログ
ブログ更新は以下に移行中です。
->Analogfeeder.com
カテゴリ:自作midiデバイス( 4 )
自作midi4
とりあえず動画です。
----------複数のスイッチ(8×8)でmidi信号送信--------------

自作midi2に対応しています。詳しくは自作midi2

-----------ツマミに反応してmidi信号送信---------------------
カメラのマイクがしょぼいので低音割れてますが。。

自作midi3に対応しています。詳しくは自作midi3

ちょっと遊びすぎですがカメラを片手で持っているので、片手しか使えません泣

送るmidi信号は自分でいじれるのでいろんな用途に使えそうです。

今後は距離センサーとか重力加速センサーと使ったりしてインタラクティブにいきたいなあ
[PR]
by toucyy | 2007-01-05 19:36 | 自作midiデバイス
自作midiデバイス3更新中
自作midiデバイス2が中途半端ですが、ときどき修正しながらやっていきます。

今回はツマミに反応してmidi信号を送ることをやります。
動画はこちらです(自作midi4にあります

今回もpicマイコンを使いますが、クロックが10MHzから20MHzに変わりました。
さらにpicも16F877Aになりました。
なぜこれになったかというと今回のツマミに反応するためにはAD変換という機能を使う必要があるからです。
AD変換とは、analog(アナログ)からdigitai(デジタル)に変換することを言います。
つまりツマミでまわす量をデジタルに変換する必要があるということです。
ツマミというのは、ボリュームとかノブとかいろいろ言われ方がありますが、電子部品的にいうと可変抵抗といいます。
可変抵抗とはその名の通り抵抗値を変えることができる抵抗のことです。
つまりツマミとは手で回すことによって抵抗値を変えられる部品だということです。
抵抗はみなさんきいたことがあると思いますが、オームの法則にでてくる
V=RI (電圧=抵抗×電流)
のRに相当する部分です。
Rが変わればIが一定ならばVが変化します。
いいかえれば、RでVをコントロールすることが出来ます。
RはここでいうツマミのことなのでVをツマミでコントロールすることをいうことがわかります。
AD変換の話に戻りますが、AD変換はそのVの変化をデジタルにすることをいいます。
つまり例を挙げると
Vが5Vだとするとデジタルならば01111111とか10進法が2進法に変わります。
これをAD変換だというのはちょっとニュアンスが違いますが、だいたいはつかめると思います。

いきなりですがアセンブラはこちらになります。(注意。アセンブラがきれいではないので更新する可能性あります。)

注意して欲しいのは、今まで使っていたmidisend関数が20MHz用に書き換えられている点AD変換特有のゆらぎ(ツマミを触っていないのに値が変化する現象)を取り除くテクニックが入っている点です。
後は今までのmidi送信にAD変換が加わっただけだと思ってもらって結構です。

-------------------アセンブラ-------------------------------
list p=16f877a
include p16f877a.inc
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF


xmit equ021h
tempequ022h
jequ023h
iequ024h
numequ025h
num1equ026h
num2 equ 027h
num3 equ 028h
c equ 029h
d equ 030h
e equ 031h

org 0

bsf STATUS,RP0
movlw b'00001110'
movwf ADCON1
clrf TRISB
bcf STATUS,RP0
movlw b'10000001'
movwf ADCON0


START
movlwD'2'
movwfi
ADSTART
CALL secdelay
bsf ADCON0,GO
WAIT
btfsc ADCON0,GO
goto WAIT
rrf ADRESH,w
andlw b'01111111'
decfszi,f
goto SS
goto SSS

SS
movwf num1
movwf num
call noteon
goto ADSTART

SSS
movwf num2
subwf num1,w ;ad2-ad1
btfss STATUS,Z
goto NUMSET ;ad1 not ad2
movlw D'1'
movwf i
goto ADSTART

NUMSET
movf num2,w
movwf num
call noteon

SSSS
call secdelay
bsf ADCON0,GO
WAIT1
btfsc ADCON0,GO
goto WAIT1
rrf ADRESH,w
andlw b'01111111'

movwf num3
subwf num1,w ;num1-num3
btfsc STATUS,Z
goto SSSS ;num1 = num3

movf num3,w
subwf num2,w ;num2-num3
btfsc STATUS,Z
goto SSSS ;num2 = num3
movf num3,w
movwf num1
movwf num
clrf num2
clrf num3
call noteon
movlw D'1'
movwf i
goto ADSTART


noteon
movlw0x90; note on, channel 1
movwfxmit
callsendmidi

movlw0x3C; middle C
movwfxmit
callsendmidi

movf num,w
movwf xmit
call sendmidi
return


sendmidi:
startb:bcfPORTB,0x02; start bit

movlwD'49'; delay 73 clocks: 2 + (23 * 3 + 1 * 2)
movwftemp; |
loop1:decfsztemp,f; |
gotoloop1; end delay

movlwD'8'
movwfj

sendloop:; executes 5 instuctions before setting bit
rrfxmit,f
btfscSTATUS, C
gotosend1

send0:nop
nop
nop
bcfPORTB, 0x02;send a 0 bit
gotoendloop

send1:nop
bsfPORTB, 0x02;send a 1 bit
nop
nop

endloop:movlwD'48';delay 70 instructions 2 + (22 * 3 + 1 * 2)
movwftemp; |
loop2:decfsztemp,f; |
gotoloop2; end delay

decfszj,f;
gotosendloop

stopb:nop
nop
nop
nop
nop
bsfPORTB, 0x02; stop bit
movlwD'51'; delay 79 clocks: 2 + (25 * 3 + 1 * 2)
movwftemp; |
loop3:decfsztemp,f; |
gotoloop3; end delay
nop
nop
return

secdelay:
movlwD'1'
movwfc
cloop:movlwD'255'
movwfd
dloop:movlwD'255'
movwfe
eloop:decfsze,f
gotoeloop
decfszd,f
gotodloop
decfszc,f
gotocloop
return

end
[PR]
by toucyy | 2006-11-29 00:39 | 自作midiデバイス
自作midiデバイス2修正中
f0097833_1414289.jpg

自作midiデバイス1の応用をやっていきましょう。

-------スイッチに反応してmidi信号を送る-------
前のアセンブラでは、こちらの意図にかかわらず、1秒ごとにmidi信号を送るだけのものでした。
これでは、何にも面白くないので、スイッチに反応してmidi信号を送るようにしてみましょう。


----------テスト動画----------
スイッチを押すごとにmidi信号送信

注意 音が出ます!!

音が悪いですが・・・
このようにかなり面白いことができそうです。



注意してほしいのがチャタリングという現象です。

チャタリングとは、機械接点がOFF→ONまたはON→OFFへ移行する際、瞬時に変化するのではなく、ON/OFFを何回か繰り返しながら状態が移行する現象のことです。

チャタリングの継続時間は、数100μs~数msと人間から見ればほんの一瞬のことで感知することはできませんが、高速な電子回路にとってはだいぶ長い間オンオフが繰り返されているように感じるはずです。
f0097833_033148.jpg

スイッチを組み込む場合、これを防ぐ必要があります。

さらに
------複数のスイッチを入力させてmidi信号を送る-------
ことをやってみます。

これは、実際にmidiデバイスを作るうえでとても有効です。
これができたらMPCみたいにできます。

さてそれをするにはどうすればいいでしょうか?

もし使っているPICの入出力端子が8個あるとしたら、スイッチは8個つなげばよいですね。
たしかに8個つないでそれぞれのスイッチが押されたときにそれぞれ違うmidi信号をおくってやればいいわけです。
しかし、8個じゃあなーあ。。と思いませんか?



実は工夫次第で、入出力端子が8個でなんと16スイッチに拡張できるのですよ!!

その便利な方法はキーマトリクスと呼ばれる方法です。
これは別に凄い方法ってわけではなく、普通に電卓とかパソコンのキーボードに使われています。


どういう仕組みかというと、
f0097833_2093927.jpg

こんな感じです。
これで8入出力で16スイッチです。

どんな感じで読みこむかというと、
0,1,2,3端子を出力、4,5,6,7端子を入力に設定します。
そして、
一番上の行の四つのスイッチの状態を読みます。
0端子をLoにして、あとの1,2,3をHiにします。
そして、4,5,6,7端子で電圧を読みます。
もし、一行目の一番左のスイッチがonならば、端子4はLoになり、ほかの5,6,7はHiのままです。
つまりonのスイッチにより、入力にLoがおくられます。
Offならば、Hiです。
次に1端子をLoにして、0,2,3をHiにします。
そして、同様に4,5,6,7を読みます。

以上のことを繰り返して、計16のスイッチの状態を作り出します。

別に4×4にしなくても、2×6とか3×5とかもできます。
けれど、8入力では、4×4が最大になりますね。

アセンブラはこちらです。(注意書き方が自己流のため更新される場合があります)
; CPU configuration
processor 16f84A
include
__config _HS_OSC & _WDT_OFF & _PWRTE_ON

; variables


tempequ H'1F'
xmitequ H'1D'
check0 equ H'0E'
j equ H'1B'
check1 equ H'0F'
cnt04 equ H'0C' ;0.4mS待つサブルーチン用カウンタ
cnt20 equ H'0D' ;20mS待つサブルーチン用カウンタ


; Program

org0


start:
bsf STATUS,RP0 ; ファイルレジスタSTATUSのRP0をセット(1)する → バンク1
movlw H'00'
movwf TRISA
movlw H'01'
movwf TRISB ; ファイルレジスタTRISAの1と2ビット目のみON → RA0とRA1は入力
bcf STATUS,RP0 ; STATUSのRP0をクリア(0) → バンク0
clrf check0

main

loopa1
movlw H'EF'
movwf PORTB
btfss PORTB,0 ; スイッチの状態チェック
goto t1 ; スイッチがONの時
bcf check0,1
loopa2
btfss PORTB,1 ; スイッチの状態チェック
goto t2 ; スイッチがONの時
bcf check0,2
loopa3
btfss PORTB,2 ; スイッチの状態チェック
goto t3 ; スイッチがONの時
bcf check0,3

loopa4
movlw H'DF'
movwf PORTB
btfss PORTB,0 ; スイッチの状態チェック
goto t4 ; スイッチがONの時
bcf check0,4
loopa5
btfss PORTB,1 ; スイッチの状態チェック
goto t5 ; スイッチがONの時
bcf check0,5
loopa6
btfss PORTB,2 ; スイッチの状態チェック
goto t6 ; スイッチがONの時
bcf check0,6

btfsc check0,1
goto loopa1
btfsc check0,2
goto loopa1
btfsc check0,3
goto loopa1
btfsc check0,4
goto loopa1
btfsc check0,5
goto loopa1
btfsc check0,6
goto loopa1
btfsc check0,0
goto loopa1
goto noteoff

t1
call T20mS
btfsc PORTB,0
goto loopa1
btfsc check0,1
goto loopa2
goto noteon1
t2
call T20mS
btfsc PORTB,1
goto loopa1
btfsc check0,2
goto loopa3
goto noteon2
t3
call T20mS
btfsc PORTB,2
goto loopa1
btfsc check0,3
goto loopa4
goto noteon3
t4
call T20mS
btfsc PORTB,0
goto loopa1
btfsc check0,4
goto loopa5
goto noteon4
t5
call T20mS
btfsc PORTB,1
goto loopa1
btfsc check0,5
goto loopa6
goto noteon5
t6
call T20mS
btfsc PORTB,3
goto loopa1
btfsc check0,6
goto loopa1
goto noteon6
noteon1:
movlw0x90
movwfxmit
callsendmidi

movlw0x3C
movwfxmit
callsendmidi

movlw0x7F
movwfxmit
callsendmidi
bcf check0,0
bsf check0,1
goto loopa1

noteon2:
movlw0x90
movwfxmit
callsendmidi

movlw0x3C
movwfxmit
callsendmidi

movlw0x3F
movwfxmit
callsendmidi
bcf check0,0
bsf check0,2
goto loopa1

noteon3:
movlw0x90
movwfxmit
callsendmidi

movlw0x3C
movwfxmit
callsendmidi

movlw0x19
movwfxmit
callsendmidi
bcf check0,0
bsf check0,3
goto loopa1
noteon4:
movlw0x90
movwfxmit
callsendmidi

movlw0x3C
movwfxmit
callsendmidi

movlw0x18
movwfxmit
callsendmidi
bcf check0,0
bsf check0,4
goto loopa1

noteon5:
movlw0x90
movwfxmit
callsendmidi

movlw0x3C
movwfxmit
callsendmidi

movlw0x17
movwfxmit
callsendmidi
bcf check0,0
bsf check0,5
goto loopa1

noteon6:
movlw0x90
movwfxmit
callsendmidi

movlw0x3C
movwfxmit
callsendmidi

movlw0x16
movwfxmit
callsendmidi
bcf check0,0
bsf check0,6
goto loopa1

noteoff;
movlw0x80
movwfxmit
callsendmidi

movlw0x3C
movwfxmit
callsendmidi

movlw0x7F
movwfxmit
callsendmidi
bsf check0,0
gotoloopa1


sendmidi:

startb:bcfPORTA, 0x02

movlwD'23'
movwftemp
loop1:decfsztemp,f
gotoloop1

movlwD'8'
movwfj

sendloop:
rrfxmit,f
btfscSTATUS, C
gotosend1

send0:nop
nop
nop
nop
bcfPORTA, 0x02
gotoendloop

send1:nop
nop
bsfPORTA, 0x02
nop
nop

endloop:

movlwD'22'
movwftemp
loop2:decfsztemp,f
gotoloop2

decfszj,f
gotosendloop

stopb:
nop
nop
nop
nop
nop
bsfPORTA, 0x02
movlwD'26'
movwftemp
loop3:decfsztemp,f
gotoloop3

return

T20mS
MOVLW D'50' ; 50(20mS)
; MOVLW D'100' ; 100(40mS)
MOVWF cnt20 ; (ループ回数として50をセット)
T20LP CALL T04mS ; 0.4mS待つ
DECFSZ cnt20,F ; ループ回数-1して0になったら次の命令をスキップ
GOTO T20LP ;
RETURN ; このサブルーチン呼出し元に戻る


; << 0.4mS待つサブルーチン >>
T04mS
MOVLW D'249' ; 249
MOVWF cnt04 ; (ループ回数として249をセット)
T04LP NOP ; 何もせず1サイクル消費
DECFSZ cnt04,F ; ループ回数-1して0になったら次の命令をスキップ
GOTO T04LP
RETURN ; このサブルーチン呼出し元に戻る
end
[PR]
by toucyy | 2006-07-06 14:09 | 自作midiデバイス
自作midiデバイス1
f0097833_14251643.jpg


自作のmidiデバイス作ります。

最近の電子楽器は標準でmidiが組み込まれているものが多くなってきています。
今後midiを通して、コンピュータとのかかわりがより深くなっていくことが予想されるので、midiをコントロールできるようになることは、独自の音楽性を売りにしている人にとってはとても重要なことです。midiがコントロールできれば、パソコン、エフェクターやシーケンサー、ドラムマシン、照明など、いろいろな要素を統合的に操ることができます。よって、今まで考えられないようなことができるようになるのです。

とくにmax/mspreaktorなど、自分でなんでも作れちゃう系のソフトでは、自作midiに興味がある人がいると思う(自分がそうだった)ので、これを機にうまいmidiが作れたらなあと思います。



では、自作midiデバイスを作るにはどうすればいいか。
まず、midi信号について知る必要があります。

-------midi信号とは?-------

簡単にいうと、楽器(ここでは鍵盤を想定します)の演奏情報です。
つまり、あなたが鍵盤の”ピアノどの音どれくらいの強さで押したか”という情報です。
これは、別に”どのつまみどのくらい回しているか”とか
どのセンサーどれくらい感知しているか”とか
なんでもいいです。
ここでは鍵盤話がもっともmidiでスタンダードなのでそれにしただけです。

ここで
上の鍵盤の話の” ”の中に太字の情報が三つあるのがわかります。
実は、midi信号とはこの三つの情報を鍵盤が押されたときにパソコンやらシンセなど送信するだけで実現できるものなのです。
なのでmidi信号そのものは、音ではないので、注意してください。ここをごっちゃにしている人がかなり多いです。
もちろん受信する側はそれを、”ピアノどの音どれくらいの強さで押したか”を認識して、実際に音を出す役割をするだけです。
これが一連のmidi信号の仕組みです。

では
-------midi信号が実際にどうゆう形で送信、受信されているのでしょうか?-------

ここからは、多少理系の知識がいるのですが、なるべく分かりやすいように書くことにします。
しかし、僕は理系の人間なので、一般の方に理解できてない言葉を平気で使う可能性があります。
なので、わからないことがあるならば気軽に書き込んでいただいて結構です。
しかし、多少のことはできるだけ自分で調べてください。
今やgoogle先生がなんでも答えてくれるでしょう。

midi信号は上の三つの情報をおくればいいのです。
ではたとえば、どれくらいの強さって情報をどうおくるの?って考えます。
てっとりばやく数値で送りましょう。たとえば、127の強さで送りましょう。
でも127って何?って、これは卑怯ですが、midi信号で送れる最大の強さなんですが、これは今わからないと思うので、ここでは扱うのに都合のいい数字だと思ってください。
では127で送れば鳴るのかというと、そうあまくなく、このままではあっち(パソコンとかシンセなど、まあ受信する側)が認識してくれないのです。

実は127っていうのは、人間が都合よく認識する為のものでしかないのです。
つまり、パソコンやら、シンセなど、、、、っていうか機械全部、127のまんまでは認識できません。
したらどうすればいいか?

-------10進法、2進法-------
いきなりですが、127は10進法と呼ばれる数字です。
しかし、それは機械では認識できないので、ここで2進法が登場します。
2進法は機械が認識できる数字です。
上の127を2進法で書くと、1111111になります。
なぜって、思う人にこれを説明するのは大変なので、この辺はgoogle先生に相談してください。

ここではwindowsのアクセサリ”関数電卓”を使って計算して確かめてもらいます。
まず、

スタートメニューからすべてのプログラム
アクセサリ→電卓

で電卓を起動してください。
あとは、電卓の上のタブの”表示”から”関数電卓”を選んでもらって、
10進法ってところを選択してもらって、127を入力します。
そして2進法を選択すれば、1111111と表示されるはずです。
これで人間数字(10進法)から機械数字(2進法)に変換されました。

このやりかたは、midiデバイスをつくるときの必要になるテクニックなので、覚えておいて損はありません。

これで127の強さを機械が認識できる1111111にできたので、これを送信すれば、あっちが勝手に認識して鳴らしてくれるわけです。

今度は、1111111って信号をどう作るかって話ですね。

-------マイコン-------
この1111111って信号を作るには”マイコン”が優れています。
マイコンとは、マイクロコンピュータとかマイクロコントローラーとかいいます。
簡単にいうと、電気を制御するものです。
人間でいうと脳にあたるのかな?
脳が手や足に命令することによって、手がどのくらい、足がどのくらい動かすのかを制御しているわけです。
ここで、midi信号を送る線(midiケーブル)はニューロンみたいなものですね。

話がそれましたが、用はマイコンが使えれば、midiデバイスが作れます。
つまりマイコンを使うことによって、11111111という信号を作れればいいわけですね。

ここでマイコンをゼロから説明するのは、大変なので、カテゴリの”picマイコン”に最低限のことを書いておきます。(picという単語に反応すると思いますが、これはマイコンの種類です。あまり気にしないでください。)
なので、マイコンが使えるような状態になるまで、ここから先の話は、実現できないので、適当に読み進めてもかまいませんし、マイコンを作りにかかってもどっちでもかまいません。
picマイコンでは、電気と2進法との関係など、ハード(電気回路)的な説明も加えたいと思います。


話をmidiに戻します。

-------midiの規格-------
上の話からmidi信号は'0'と'1'の数字の組み合わせで表現できることがわかりました。
ここでもし、送りたい信号が'10000000'だとしたら、これは、数字が8個ならんでいるので8bit(ビット)と表現されます。
さらに8bitを1byte(バイト)ともいいます。

ここでいきなりmidiの規格について書くと、

midi信号は、転送速度31.25Kbit/sec(誤差±1%)非同期シリアル転送で伝えられるデジタル信号で、各データは8ビットで構成されます。

転送速度31.25Kbit/secとは、一秒間に31250bitの信号をおくりますよっていう速さのことです。
つまり'0'か'1'の数字を一秒間に31250個送るってことです。
非同期シリアル転送とは、送信側と受信側のタイミングを合わせないで、データのやり取りする方法です。
どういうものかというと(下図参照)
スタートビット→データバイト(ビット0、…ビット7の塊)→ストップビットの順番に、計10ビットで転送される方法で、
スタートビットは論理0、ストップビットは論理1で、受信側におくるものです。
受信側はこのスタートビットを認識して、データがおくわれてくるかを探っています。
そしてmidiはこのデータバイトの部分にメインのmidi信号を入れて送ります。

一般にバイトと最下位ビットをLSB(Least Significant Bit)といい、最上位ビットをMSB(Most Significant Bit)といいます。

MIDIではステータスバイトデータバイトの区別にMSBをつかい、1のときをステータスバイト、0のときをデータバイトとします。
そして、残りを有効なデータとして使います。
つまりMIDIにおいて1バイトで表現できるデータは7ビット分0~127(0h~7Fh)しかありません。
3バイトのmidiデータ(点線で囲まれている部分)には

ノートオン
ノートオフ
コントロールチェンジ
etc....

があります。
midiでは1バイトを転送する際には32.0μsecぐらい(ここでは31.6μs)が必要です。


という感じにかけます。
いきなりすぎてわからないと思いますが↓の図を見ればなんとか分かると思います。
詳しくは、自作midiデバイス2に書こうかな?それかmidi信号でgoogle先生に聞いてください。

f0097833_17535677.jpg


-------midiケーブルの仕組みとpicマイコンとの接続-------
midiケーブルは、下図のように5つの端子で構成されているのですが、実際使うのは、2つの端子だけ(4と5)です。
picマイコンのRA2midiの45V電源midiの5に接続すれば、完成です。

f0097833_17522595.jpg



間に抵抗220Ωをつけるのを忘れずに。
実はめちゃくちゃシンプルにできるんです。



とりあえずマイコンにこのアセンブラを書き込んで動作を確認しましょう。

-------アセンブラプログラム---------------------------------------------
ノートオンとノートオフをおくるプログラムです。


;MIDISEND.ASM
;10MHz PIC16F84 microcontrollerで動きます。
;毎秒ごとにmidiメッセージを送ります。
;rewrited 2006/06/22

                         ; CPU configuration
processor 16f84              ;マイコンの種類の選択
include
        __config _HS_OSC & _WDT_OFF & _PWRTE_ON 
                         ;オシレータを4MHzから20MHz
;ウォッチドックタイマ無効
                         ;パワーアップタイマ有効

                         ; 変数

temp equ  H'1F'
xmit  equ  H'1D'
i     equ  H'1C'
j     equ  H'1B'
k     equ  H'1A'

                         ; プログラム

org0             ; リセットベクタの0番地を指定


start:
bsf STATUS,RP0 ; ファイルレジスタSTATUSのRP0をセット(1)する → バンク1
movlw H'00'
movwf TRISA ; ファイルレジスタTRISAのすべてのポートを出力設定
bcf STATUS,RP0 ; STATUSのRP0をクリア(0) → バンク0
bsf PORTA, 0x02    ;RA2をmidi出力

mainloop:

call secdelay        ; secdelay関数の呼び込み(1秒待ち)

movlw 0x90         ; ノートオン、チャンネル1
movwf xmit    ;xmitに10010000(Ox90)を格納
call sendmidi        ;sendmidi関数を呼び込み(midi信号を送る)

movlw 0x3C         ; ミドルC
movwf xmit         ;xmitに01110000(Ox3C)を格納
call sendmidi     ;sendmidi関数を呼び込み(midi信号を送る)

movlw 0x7F         ; ベロシティー127
movwf xmit     ;xmitに01111111(Ox3C)を格納
call sendmidi     ;sendmidi関数を呼び込み(midi信号を送る)

call secdelay      ; secdelay関数の呼び込み(1秒待ち)

movlw 0x80         ; ノートオフ、チャンネル1
movwf xmit         ;xmitに10000000(Ox90)を格納
call sendmidi        ;sendmidi関数を呼び込み(midi信号を送る)

movlw 0x3C         ; middle C
movwf xmit
call sendmidi

movlw 0x7F         ; velocity 127
movwf xmit
call sendmidi

goto mainloop    ; mainloopに戻る(無限loop)

sendmidi:               ;ここから重要いろいろ使いまわして

startb:bcfPORTA, 0x02    ; スタートビット

movlw D'23'       ; delay 70 サイクル: 2 + (22 * 3 + 1 * 2)
movwf temp       ; 0.4μs * 70 = 28.0μs
loop1:
decfsz temp, f      ; |
goto loop1         ;end delay

movlwD'8'         ; midi信号は8ビット 28.4μs
movwfj ;28.8μs

sendloop:         
rrfxmit, f ; xmitの内容を右に1ビットシフトしてSTATUSのCに入れる 29.2μs
btfsc STATUS, C ; STATUSのCが0ならば、gotoをスキップ、1ならばgoto 29.6μs
goto send1 ;30.4μs

send0:
nop ;30.0μs
nop ;30.4μs
nop ;30.8μs
nop ;31.2μs
bcfPORTA, 0x02     ;0ビットを送る 31.6μs
goto endloop

send1:
nop ;30.8μs
nop ;31.2μs
bsfPORTA, 0x02     ;1ビットを送る 31.6μs
nop
nop

endloop:           ;

movlw D'22'       ;delay 67 instructions 2 + (21 * 3 + 1 * 2)
movwf temp       ; 0.4μs * 67 = 26.8μs
loop2:
decfsz temp, f  ; |
goto loop2         ; end delay

decfsz j, f          ;
goto sendloop

stopb:
nop
nop
nop
nop
nop
bsfPORTA, 0x02        ; ストップビット
movlw D'26'           ; delay 79 サイクル: 2 + (25 * 3 + 1 * 2)
movwf temp           ; |
loop3:
decfsz temp, f          ; |
goto loop3            ; end delay

return

; secdelay delays for one second ( 2500000 instructions )
; kloop = (2 + 254 * 3 + 1 * 2) = 766
; jloop = 2 + kloop * 255 + (3 * 254 + 1 * 2) = 196096
; iloop = 2 + jloop * 13 + (3*254 + 1*2) = 2550014 = 1.02 seconds
; x =
secdelay: ;secdelay関数(1秒を作るため)
movlw D'13'
movwf i
iloop:
movlw D'255'
movwf j
jloop:
movlw D'255'
movwf k
kloop:
decfszk, f
gotokloop
decfszj, f
gotojloop
decfszi, f
gotoiloop

return

end

---------------------------------------------------------------------


上のアセンブラをコピベだとうまくいかないことがあるので、これをダウンロードしてください。
testmidi2.asm


sendmidi関数が重要です。
ここがソフトフェア的にmidi送信する核の部分です。

もう一度書くと、
MIDIは、転送速度31.25Kbit/sec(誤差±1%)非同期シリアル転送で伝えられるデジタル信号で、各データは8ビットで構成されます。
また、スタートビット、ビット0、…ビット7、ストップビットの順番に、計10ビットで転送されます。スタートビットは論理0、ストップビットは論理1で、MIDIで1バイトを転送する際には32.0μsecぐらいが必要です。

この関数では、79サイクル毎くらいでデータを送信しています。
なので0.4μs×79=31.6μsごとにデータ送信しています。

実はmidi送信にはUART回路とかUSART回路が内蔵しているマイコンを使う場合

使わないでソフトウェア的にUART回路とかUSART回路を想定して行う場合とがあります。
マイコンでmidi送信するにはシリアル転送と同じようなものなのでUART回路とかUSART回路を使うほうが楽なんですが、実はUART回路とかUSART回路がよくわかんないので、
今回はソフトフェア的にmidi送信しています。
すこし調べて分かったら書きます。

いろいろ応用することを考えるならば、ここを理解する必要があります。

上のアセンブラプログラムを解読すれば、分かると思います。



-------test動画-------
簡単なmax/mspのパッチを作って試してみました。
pic16f84で1秒ごとにmidi信号送信

1秒ごとにmidi信号がパソコン(max/msp)送られていることがわかります。
あとは、このアセンブラをどう料理するかは、あなたしだいですよーー!

次回はスイッチに反応させます。
[PR]
by toucyy | 2006-06-25 14:21 | 自作midiデバイス


PRODUCTS


レコードでの演奏(シンセサイザー)を可能にする
"Anvs"(アンブス) - Analog Vinyl Synthesizer -

Midi信号を他出力する
"Midiv" -Midi Distributor Divider-

ターンテーブルアニメーションを可能にする
"Taf1" -Turntable Animation Flasher-

LEDを使用したトリッキーな映像制作装置
(Taf1の機能拡張版)
"Taf2" -Turntable Animation Flasher 2-



PROFILE




Toucyy

某外資系半導体メーカー勤務、その傍らDJの経験とハードウェア、ソフトウェアエンジニアリングのバックグランドを生かし活動中。自作電子楽器でLive & DJ

patlo (yamamo2 + toucyy)
picnome、picratchbox開発者yamamo2さんとユニット組み、本格的に自作電子楽器でLiveやってます。

電子楽器と音楽と人とのつながりをいろいろ考えるのが最近のはまり。

------CONTACT------
"toucyyアットgmail.com"
(メールを送信する際はアットを@に変えてください。スパム対策用です)



イベント&ライブ等


2010年5月22~23日 MTM05 出展とプレゼンテーション "anvs"
http://www.oreilly.co.jp/mtm/05/
2010年11月20~21日 MTM06 出展 "anvs modular"
http://www.oreilly.co.jp/mtm/06/
2010年11月21日 Analog Synthesizer Builders' Summit 出展 "anvs modular"
http://analog-synth.jp/summit10/e_index.html
2011年12月3~4日 MTM07  出展 "Taf"
http://www.oreilly.co.jp/mtm/07/

2012年1月14日 TMUG20 (Tokyo Max Users Group) プレゼンテーションとライブデモ
http://tokyomax.jp/?p=1670
2010年7月10日 TMUG16 (Tokyo Max Users Group)  ライブ
http://tokyomax.jp/?p=696
http://toucylab.exblog.jp/14084312/




紹介記事



もうライブで使えるレベル――DIY楽器がますます進化



10th Analog Synthesizer Builders' Summit Party



Engadget Japan



ASCII.jp 「理屈にあわない楽しさを求めて 電子楽器をつくる人の哲学」



Sampling Loveのblog



VESTAX JAPAN



メディア&SNS



twitter

YouTube

DJイベント
"Elements"

茨城を拠点にさまざまな"要素"にこだわり行っているイベント

"Ruckus
[toucylab custom ver 1.2]"



PSP用のDJソフトウェアです。 Captain Dan氏のRuckusをベースにコントロールの微調整を行いました。
Download here !
-------------------------
カテゴリ
このブログは?
日々思ったこと&できごとなど
Anvs(アンブス)
Anvs製作日記
写真
自作ミキサー&アンプ
自作midiデバイス
Ableton Live tips
Dj&Live&Events
midi_crossfader
crossfader メンテナンス
mixer カスタマイズ
MPC2000 カスタマイズ
lighting(電飾プロジェクト)
kp2モバイル化
max/msp
自作サンプラー&エフェクター案
PSP関係
picマイコン
Blackfin
ケース加工&シルク印刷
Favorite URL(要Login)
books
Apple
Taf
midiv
Oto Devices
sketchup (eagleup)
eagle
mbed
その他のジャンル
ブログジャンル