
1つの赤外線LEDでモーターを制御している様子
赤外線LEDは、赤外線(波長850nm)で光るLEDの一種。
付けたり消したりすることで信号を送っています。
NECフォーマットでは、1秒に3.8万回の点滅(38kHz)が基本。
次のIchigoJam BASICの高速エルチカプログラムでも・・・
1 LED1:WAIT1 2 LED0:WAIT1 3 GOTO1
これで、1秒間に約30回、30Hzエルチカ。この1000倍速く点滅させる必要があります。
1秒間に5000万回計算できる100円コンピューターくんが本気を出せる言語、マシン語の登場!
@ON R1=22 @ON_LOOP [R3]L=R4 GOSUB @WAIT631 [R3]L=R6 GOSUB @WAIT631 R1-=1 IF !0 GOTO @ON_LOOP RTN @WAIT631 R5=154 R5-=1 IF !0 GOTO -1 RET
レジスタR3に、LEDがつながっているOUTポートを制御するメモリマップドI/Oのアドレス、R4にON、R6にOFFの値をセットし、上記プログラムで38kHzエルチカさせます。
631サイクル待つサブルーチン、@WAIT631を使って38kHzを実現。メモリへの代入に2サイクルを加えた、633サイクルは、48MHzで37.9kHz。(48*1000*1000)/633/2 = 37914(Hz)。(参考、マシン語とサイクル数は、Cortex-M0 Armマシン語表より)
カスタマーコードを上位8bit、データを下位8bitにセットして、OUT1につないだ赤外線LEDを使って、NECフォーマットで送信するマシン語を作ります。
U=USR(AD,0x0015)
データを入力すると送信する、IchigoJam BASICにしたプログラム全文がこちら。
10 POKE#700,112,181,114,182,255,38,1,70,49,64,204,67,52,64,5,10,53,64,234,67,50,64,32,6,11,4,24,67,19,2,24,67,40,67,80,35,27,2,1,51,27,4,4,51,1,36,0,38,172,33,73,0,28,96,0,240,45,248,30,96,0,240 20 POKE#73E,42,248,1,57,247,209,172,33,0,0,0,0,0,240,35,248,0,0,0,0,0,240,31,248,1,57,245,209,33,34,22,33,28,96,0,240,24,248,30,96,0,240,21,248,1,57,247,209,22,33,32,66,0,208,66,33,0,0,0,0,0,240 30 POKE#77C,11,248,0,0,0,0,0,240,7,248,1,57,245,209,64,8,1,58,229,209,98,182,112,189,154,37,1,61,253,209,112,71 40 M=#00:INPUT C:GSB@C:CONT 50 @C:?USR(#700,M<<8+C):RTN
こちらが生成元のasm15マシン語のプログラムです。
@INIT PUSH {LR,R4,R5,R6} ' レジスタ保存 CPSID ' 割り込み禁止 ' IN : R0 = 0xMMCC (MM=メーカー8bit, CC=コマンド8bit) ' OUT: R0 = [~cmd_sw][cmd_sw][~mfg_sw][mfg_sw] ' regs used: R0-R6 only R6=255 ' 0xFF マスク R1=R0 R1&=R6 ' R1 = cmd R4=~R1 R4&=R6 ' R4 = cmd_inv R5=R0>>8 R5&=R6 ' R5 = mfg R2=~R5 R2&=R6 ' R2 = mfg_inv ' out = (cmd_inv<<24)|(cmd_sw<<16)|(mfg_inv<<8)|mfg_sw R0=R4<<24 R3=R1<<16 R0|=R3 R3=R2<<8 R0|=R3 R0|=R5 @SEND ' R0 LSBから32bit送るデータ R3=#50 ' OUT1 の address PIO1_0 R3=R3<<8 R3+=1 R3=R3<<16 R3+=`00000100 'PIO1_0 R4=1 'PIOオン用 R6=0 'PIOオフ用 @HEADER @ON_H R1=172 R1=R1<<1 ' 2倍 @ON_LOOP_H [R3]L=R4 GOSUB @WAIT631 [R3]L=R6 GOSUB @WAIT631 R1-=1 IF !0 GOTO @ON_LOOP_H @OFF_H R1=172 @OFF_LOOP_H NOP NOP GOSUB @WAIT631 NOP NOP GOSUB @WAIT631 R1-=1 IF !0 GOTO @OFF_LOOP_H @BODY R2=33 'カウンタ 33回回す @ON R1=22 ' 11x2 固定 @ON_LOOP [R3]L=R4 GOSUB @WAIT631 [R3]L=R6 GOSUB @WAIT631 R1-=1 IF !0 GOTO @ON_LOOP @OFF R1=22 ' 0のとき11x2、1のとき33x2 R0&R4 'R4=1 IF 0 GOTO @OFF_LOOP R1=66 @OFF_LOOP NOP NOP GOSUB @WAIT631 NOP NOP GOSUB @WAIT631 R1-=1 IF !0 GOTO @OFF_LOOP R0=R0>>1 R2-=1 IF !0 GOTO @ON @END CPSIE ' 割り込み許可 POP {PC,R4,R5,R6} ' RET @WAIT631 'use R5 R5=154 ' 1cycle '(48000/38/2=631 - overhead 5cycle (+10/2) - 5) / 4 = 154 R5-=1 ' 1 cycle IF !0 GOTO -1 ' 分岐するとき3cycle しないとき1 - 4*loop-2 = 618 RET ' 3cycle
まずカスタマーコード、データコードから反転付きの32bitの送信用データを作成し、ヘッダー送信、33回ループで信号送信と続け、BASICに制御を戻しています。R4からR6はスタックに積んでおき、制御を返す時に元の値に戻します。
赤外線リモコンで動く家電を探して、いろいろ遊んでみよう!
links
- IchigoJamで赤外線リモコンNECフォーマットをデコード、タミヤローリングロボ制御コード一覧
- IchigoJamで作るIoT学習リモコン、古いエアコンもスマホ制御で快適に! インターン生も芸人さんも楽しいプログラミング入門とマシン語
- タミヤのローリングロボとレゴテクニック連結治具
- 赤外線リモコンの通信フォーマット
赤外線リモコンで制御する
Boxで共有されるファイル郡。まとめてダウンロードしたくなったら調べるAPi、アプリケーション・プログラミング・インターフェイス。


