福野泰介の一日一創 - create every day

マシン語の気持ちいいところは、実行時間が正確に読めるところ。
割り込みを止めて、各命令の所要クロック数を数えることで、さまざまなデバイスとつながります。

一応動いた「DMX512対応の照明」仕様書とちょっと違った動きの謎は、オシロスコープで解けました。

照明業界の標準規格「DMX512」は、250kbpsの差動信号によるシリアル通信で、25byte〜513byteまでを一塊にデータを送る仕様です。(ケーブル加工方法
塊の始まりを示す信号などに特徴があり、stopbitもIchigoJamの標準1bitと異なるので、IchigoJamのシリアル通信を使わず、OUT1とOUT2ポートで制御することにします。

とはいっても、250kbpsとは、1bitを4μ秒で表現となかなかに高速なため、IchigoJam BASICでは追いつきませんし、C言語では細かい時間が合わせができません。 そこで登場、マシン語です!

1命令、約21nsec(21ナノ秒=1/48MHz)で動くIchigoJamのArmマシン語なら、この1bitの送信時間内に192クロック分使えるので、十分に対応できそうです。

まずはループを使って正確に待つプログラムをつくります。

@WAIT R0-=1 IF !0 GOTO @WAIT RET

Armマシン語表を見て、必要クロック数を計算します。
R0-=1 は 1
IF !0 はジャンプする時 3、しない時 1
RET は 3
ということで、R0が1のときは5クロック、2で9、3で13・・・R0*4+1クロック分、待ちます。
R0に30000を指定すると、1/48000000*(30000*4+1)*1000=2.5m(秒)
R0に183を16bit左シフトした値で、約1秒となります。

R0=R0<<16 @WAIT R0-=1 IF !0 GOTO @WAIT RET

これをマシン語に変換して、TICKで測ってみましょう

[0]=`00000 10000 000 000 :'r0=r0<<16 [1]=`00111 000 00000001 :'r0-=1 [2]=`11010001 11111101 :'if!0goto@wait [3]=`01000111 01110000 :'ret CLT:U=USR(#800,183):?TICK() 126

おや、1秒=60のはずが2秒ちょっとかかってしまいました。
実はこの差は割り込みから来ます。IchigoJamは常時、画面出力処理を割り込み処理によって行っているので、その分遅くなってしまうわけです。

VIDEO0:CLT:U=USR(#800,183):?TICK():VIDEO1 69

だいぶ1秒に近づきました。ただ実はまだフルスピードではないのです。TICK()の値すすめるために内部でのカウントや、キーボードの割り込みなどが残っています。 完全に割り込み処理を止めるマシン語、CPSID(割込禁止)とCPSIE(割込許可)を使います。

CPSID R0=R0<<16 @WAIT R0-=1 IF !0 GOTO @WAIT CPSIE RET

アセンブル

[0]=`1011011001110010 :'CPSID [1]=`00000 10000 000 000 :'r0=r0<<16 [2]=`00111 000 00000001 :'r0-=1 [3]=`11010001 11111101 :'if!0goto@wait [4]=`1011011001100010 :'CPSIE [5]=`01000111 01110000 :'ret CLT:U=USR(#800,183):?TICK() 0

画面出力が一旦途切れて、1秒後戻ってきましたか?
TICK()の数値が0になるのは、割り込み処理が完全に止まっていた証拠です。

正確に待ち時間をコントロールすることができるようになったので、DMX512制御プログラムを作ってみます。
制御コードと24ch〜512chのデータを1byteずつ送るので、送るチャンネル数の半分を先頭に指定し、制御コード、チャンネルデータと指定することにして、マシン語プログラムを作ります。

' R0 - 開始アドレス 送信数/2、送信コード(0)、ch1、ch2・・・送信個数分 ' R1 - base address (初期はRAM offset) ' R2 - OUT value (初期はROM offset) R2=1(on) R2=2(off) ' R3 - DMX value ' R4 - loop1 ' R5 - loop2 ' R6 - #100 ' R7 - loopwait @DMX512 PUSH {LR,R4,R5,R6,R7} CPSID R0=R0+R1 R1=#50 'R1=#50010000 GPIO1 R1=R1<<8 R1+=1 R1=R1<<16 R6=#80 R6=R6<<1 R2=2 [R1+`11]L=R2 R7=4 'wait 22*192clock R7=R7<<8 R7+=29 GOSUB @WAIT R2=1 [R1+`11]L=R2 R7=93 GOSUB @WAIT R4=[R0] R4=R4<<1 R4+=1 R0+=1 @LOOP2 R2=2 [R1+`11]L=R2 R7=45 GOSUB @WAIT R5=1 R3=[R0] @LOOP3 R2=2 R3&R5 IF 0 GOTO @SKIP R2=1 @SKIP [R1+`11]L=R2 R7=44 GOSUB @WAIT R5=R5<<1 R5-R6 IF !0 GOTO @LOOP3 R2=1 [R1+`11]L=R2 R7=93 GOSUB @WAIT R0+=1 R4-=1 IF !0 GOTO @LOOP2 CPSIE POP {PC,R4,R5,R6,R7} @WAIT R7-=1 IF !0 GOTO @WAIT RET

asm15を使ってアセンブル。
DMX512の端子、1をGND、2をOUT1、3をOUT2へ接続。
初期設定としてOUT1が1、OUT2が0をプログラムに加えてテストします。

10 POKE#700,240,181,114,182,64,24,80,33,9,2,1,49,9,4,128,38,118,0,2,34,202,96,4,39,63,2,29,55,0,240,37,248,1,34,202,96,93,39,0,240 20 POKE#728,32,248,4,120,100,0,1,52,1,48,2,34,202,96,45,39,0,240,23,248,1,37,3,120,2,34,43,66,0,208,1,34,202,96,44,39,0,240,13,248 30 POKE#750,109,0,181,66,244,209,1,34,202,96,93,39,0,240,5,248,1,48,1,60,229,209,98,182,240,189,1,63,253,209,112,71 40 OUT1,1:OUT2,0 RUN OK POKE#800,12,0,255,0,0,255:U=USR(#700,#800) OK

CH1〜4に設定した、DMX512対応の照明「Lixadaステージライト」が青く光ったら成功です!
この照明の仕様は、1byte目に全体的な明るさ(0-127/255)や点滅(128-250)や、2〜4byte目でR/G/Bの明るさを指定するとありました。 チャンネル数は照明によって異なり、ムービングライトの場合X/Y軸の値なども合わせて指定するためチャンネル数は多くなります。

ランダムに原色を混ぜた7色をじわっと光らせ、じわっと消すプログラムはこうなります。

100 R=RND(7)+1:G=R>>1&1:B=R>>2&1:R=R&1 110 FOR I=0 TO #FF STEP 4 120 POKE#800,12,0,255,R*I,G*I,B*I 130 U=USR(#700,#800) 140 NEXT 150 FOR I=#FF TO 0 STEP -4 160 POKE#800,12,0,255,R*I,G*I,B*I 170 U=USR(#700,#800) 180 NEXT 190 GOTO 100

プロトコルのマシン語制御、うまくいかないときに便利、オシロスコープ!
Break信号の長さがちょっと長かったのでおかしかったと判明。WAITするカウントを1減らして修正完了!

信号の反射を防ぐために、ターミーターを作って接続しておくと良さそうです。(2と3を120Ω1/4Wでつなぐ)
DMX512について|サウンドハウス

DMX512に対応したスモークマシンも!
DMXに対応した自作デバイスづくりにもぜひ挑戦してみてください!

links
- 最大512chの照明コントロール!照明界の標準DMX512 x IchigoJam
- DMX512について|サウンドハウス
- "DMX512 照明"で検索 on Amazon

- 連載、IchigoJamではじめる、Armマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法
12. レジスタ不足に上位レジスタとスタック操作

ライブを盛り上げるたくさんの照明。どう制御してるか気になってました。
その答はDMX512という250kbpsの差動信号シリアル通信プロトコルにありました。


IchigoJamで照明を自由自在に操れました!


DMX512に対応した照明、一番安くて2,000円ほど!("DMX512 照明"で検索 on Amazon
XLRケーブルという3ピンのケーブルをデイジーチェーン(数珠つなぎ)で使います。
IchigoJamと接続用にXLRソケットを準備しましょう。


3ピンなので工作は簡単、1がGND、2が+、3が-(2の反転信号)です。


照明2つをIchigoJamから原色を使った7色をキラキラ切り替えるデモ

1 'DMX512 TEST 10 POKE#700,240,181,114,182,64,24,80,33,9,2,1,49,9,4,128,38,118,0,2,34,202,96,4,39,63,2,29,55,0,240,35,248,1,34,202,96,93,39,0,240 20 POKE#728,30,248,4,120,1,48,2,34,202,96,45,39,0,240,23,248,1,37,3,120,2,34,43,66,0,208,1,34,202,96,44,39,0,240,13,248,109,0,181,66 30 POKE#750,244,209,1,34,202,96,93,39,0,240,5,248,1,48,1,60,229,209,98,182,240,189,1,63,253,209,112,71 40 OUT1,1:OUT2,0 100 POKE#800,12,0 110 FOR I=0 TO 1 120 R=RND(7)+1:POKE#802+I*4,255,R&1*#FF,R>>1&1*#Ff,R>>2*#FF 130 NEXT 140 U=USR(#700,#800) 150 WAIT30 160 GOTO110

250kbpsの差動信号を仕様に基づきマシン語化。一応動きましたが、説明書記載とは違うので、どこか間違っていそう。 オシロスコープで確認&デバッグしてから詳しく解説します。(追記、解説記事、上記修正しました)

ふわっち or FAN LIVEなど、誰でもライブが手軽にできる時代。
音楽に合わせてライティングを変えたり、手元のコントローラーで演出したり、ゲームの特殊効果にも使えそう!

コンピューター制御できる照明で、一味違った配信などいかがでしょう?

links
- DMX512-A / Wikipedia
- DMX512 x IchigoJam - 解説記事

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / アイコン画像 / プロフィール画像