SONY NEX のリモコンシャッターのコマンドは以前のトピックで書いたように、
[リーダー 1011 0100 1011 1000 1111 休止] x 5回 = 225mSec
の赤外線発光パターンを送ればいいだけです。
具体的にどう発光すればいいかというと
40kHzでDuty1:2のキャリアを使って、リーダーに当たる発光パターン、論理1に当たる発光パターン、・・・・という順番をきちんと5回繰り返せばいいわけです。
40kHzというのは1波長の長さが1秒÷40000=25μ(マイクロ)秒であり、Duty(デューティ)1:2というのはそれを1対2にわけて信号にするという意味です。
25÷3x1=8.333μ秒、25÷3x2=16.666μ秒、なのでプログラム上は8マイクロ秒オン、17マイクロ秒オフの出力パターンを作ることにします。便宜上25μ秒だけ送出することはないので2回繰り返してサブルーチン化しています。
リーダーは信号送出中が2500μ秒+送出無し550μ秒でできていますので上図でいうキャリア50μ秒を50回繰り返すと2500μ秒になります。そして550μ秒オフにします。
論理1は送出中1250μ秒+送出無し550μ秒。
論理0は送出中650μ秒+送出無し550μ秒。
フレーム長45000μ秒なので計算上、休止時間は10750μ秒となります。
フレーム45000μ秒を5回繰り返して(45ms x 5 = 225ms)シャッターコマンドの完成です。
PIC10F222 を選択した理由は汎用入出力ピンが4本あり、3本を入力、1本を出力に割り当てられること、3本がWeak-Pull-Up機能を持ち、外付けの部品が少なくて済むこと、小さくて(3mm四方)場所を取らないことです。
また、自前のRC発振回路(4MHz)を内蔵していて1命令(4サイクル必要)がちょうど1μ秒になります。発振回路も個体ごとにキャリブレーション値が書き込んであり精度を保つ工夫があります。
この表を見てわかるように、GP2以外は内部プルアップがあるのでそれを入力3ビットとして利用できます。プルアップというのは外部からの信号がないときに電圧をHighレベルに持ち上げる働きをいいます。もしこの機能がない場合、入力信号が不定にならないように外部で抵抗を取り付けてあげる必要があります。
あとは赤外線LEDをどうやって光らせるか検討します。
PICの出力は20mA(吸い込みも20mAまで)と定格があり、小電流のLEDなら直接駆動することもできます。しかし、今回の赤外線LEDは、Vf=1.3V、50mA、です。
トランジスタかFETで信号を増幅させます。といってもトランジスタならベース、FETならゲートに信号を送って、電池と直接つながったラインにLEDを置けばいいだけです。
なのでとても簡単な回路となりました^^。
LEDに直列に入れる抵抗は (5.0V-1.3V)÷0.05A=74Ω程度でそれを下回らなければいいので手持ちの82Ωを選択しました。
PICに乗せるプログラムはとてもシンプルです。
1.電源オンでスイッチ0~2の入力値を読みに行く。
スイッチが閉じていると電圧0VでLow、開いていると内部プルアップにより約5VでHigh。
2.スイッチ0~2の3ビット8パターンに対応してテーブルを見る。
3.最初だけ電源オンから約2.3秒でLED発光。
4.参照したテーブル値にある秒数だけ待ち。
5.1秒-225m秒=775m秒だけ待ち。
6.LED発光(225m秒)、4へ戻る。
例えば、スイッチがすべて閉じて3つともLowのときは、テーブル0番目を見に行き、3秒という値を拾ってきます。最初2秒経過で一回発光したあとは3秒まってさらに775ミリ秒待って次のLED発光になります。このスイッチパターンは4秒ごとのインターバルというわけです。
気づいたかも知れませんが、動作中にスイッチを切り替えてもインターバル値を変更できません。そこは電源オフオンで対応します。本当はInterrupt-On-Pin-Changeという機能を使って割り込みを使って入力値の再読み込みをすれば可能ですが、オフオンで十分と判断しました。
プログラムはもっと短く書けるのですが、PIC10シリーズはコールスタックが2段しかなく、CALLルーチンは2回しかネストできません。3回目CALLしてしまうと1回目の呼び元に返れません。
プログラムメモリが512命令まで、変数領域が23バイトのPIC10F222に209命令でプログラムが書けました。割り込みなど全く無いシンプルな待ちループばかりなので読解も楽かと思います。
;********************************
; PIC10F222
; 2012-12-29
; Author: HoyoHoyo
;********************************
LIST P=pic10f222
#include <p10f222.inc>
__CONFIG _IOSCFS_4MHZ & _MCPU_ON & _WDT_OFF & _CP_OFF & _MCLRE_OFF
;*********** Variables **********
CBLOCK 09h
wC0
wC1
wC2
wC3
wC4
wC5
Isave
WCnt
TCnt
ENDC
;*********** Initial ************
ORG H'0000'
MOVWF OSCCAL ;OSCCAL Set
MOVLW B'10010111' ;Option Register Set
OPTION
CLRF ADCON0 ;A/D Converter Off
MOVLW B'00001011' ;only GP2 out
TRIS GPIO
CLRF GPIO
CALL Shortwait
MOVF GPIO,W
MOVWF Isave
CLRF WCnt
BTFSC Isave,3
BSF WCnt,2
BTFSC Isave,1
BSF WCnt,1
BTFSC Isave,0
BSF WCnt,0
MOVFW WCnt
CALL WaitCnt
MOVWF WCnt
;********* Main Routine *********
main
CALL Shortwait
CALL Shortwait
blink
CALL BlinkIr
CALL Longwait
CALL Shortwait
GOTO blink
;********* Long Wait ************
Longwait
MOVFW WCnt
MOVWF TCnt
Longwait_1
NOP
MOVLW 0x06
MOVWF wC3
Longwait_2
MOVLW 0xD8
MOVWF wC4
Longwait_3
NOP
NOP
MOVLW 0xFF
MOVWF wC5
DECFSZ wC5,F
GOTO $-1
DECFSZ wC4,F
GOTO Longwait_3
DECFSZ wC3,F
GOTO Longwait_2
MOVLW 0xFB
MOVWF wC3
DECFSZ wC3,F
GOTO $-1
DECFSZ TCnt,F
GOTO Longwait_1
RETURN
;********* Short Wait ************
Shortwait
MOVLW 0x05
MOVWF wC3
Shortwait_2
NOP
NOP
MOVLW 0xC9
MOVWF wC4
Shortwait_3
NOP
NOP
MOVLW 0xFF
MOVWF wC5
DECFSZ wC5,F
GOTO $-1
DECFSZ wC4,F
GOTO Shortwait_3
DECFSZ wC3,F
GOTO Shortwait_2
MOVLW 0x24
MOVWF wC3
DECFSZ wC3,F
GOTO $-1
NOP
RETURN
;********* Table ****************
WaitCnt
ADDWF PCL,F
RETLW 0x03
RETLW 0x07
RETLW 0x0B
RETLW 0x0F
RETLW 0x13
RETLW 0x17
RETLW 0x1B
RETLW 0x1F
;********* Blink Ir *************
BlinkIr
MOVLW 0x05
MOVWF wC2
Loop
CALL Leader
CALL Log1
CALL Log0
CALL Log1
CALL Log1
CALL Log0
CALL Log1
CALL Log0
CALL Log0
CALL Log1
CALL Log0
CALL Log1
CALL Log1
CALL Log1
CALL Log0
CALL Log0
CALL Log0
CALL Log1
CALL Log1
CALL Log1
CALL Log1
CALL interv
DECFSZ wC2,F
GOTO Loop
RETURN
;********* Subroutines **********
Log0
MOVLW 0x1A
MOVWF wC1
Log0_1
BSF GPIO,GP2
MOVLW 0x02
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
CLRF GPIO
MOVLW 0x04
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
DECFSZ wC1,F
GOTO Log0_1
MOVLW 0x15
MOVWF wC1
Log0_2
MOVLW 0x07
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
DECFSZ wC1,F
GOTO Log0_2
MOVLW 0x06
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
RETURN
Log1
MOVLW 0x32
MOVWF wC1
Log1_1
BSF GPIO,GP2
MOVLW 0x02
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
CLRF GPIO
MOVLW 0x04
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
DECFSZ wC1,F
GOTO Log1_1
MOVLW 0x15
MOVWF wC1
Log1_2
MOVLW 0x07
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
DECFSZ wC1,F
GOTO Log1_2
MOVLW 0x06
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
RETURN
Leader
MOVLW 0x64
MOVWF wC1
Leader_1
BSF GPIO,GP2
MOVLW 0x02
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
CLRF GPIO
MOVLW 0x04
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
DECFSZ wC1,F
GOTO Leader_1
MOVLW 0x15
MOVWF wC1
Leader_2
MOVLW 0x07
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
DECFSZ wC1,F
GOTO Leader_2
MOVLW 0x06
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
RETURN
interv
MOVLW 0xD6
MOVWF wC1
interv_1
MOVLW 0x0F
MOVWF wC0
NOP
DECFSZ wC0,F
GOTO $-1
DECFSZ wC1,F
GOTO interv_1
MOVLW 0x0D
MOVWF wC0
DECFSZ wC0,F
GOTO $-1
NOP
NOP
RETURN
;********* OSCCAL Set ***********
ORG H'1FF'
MOVLW 0x1C
END