自転車用テールライト改造 その2

1.27mm ピッチのユニバーサル基板を使う事にします。 これがもの凄く目が細かいのでビビります。

▼ オリジナルと同じ大きさにカット!

フラットパッケージ版 PIC12F629 を基板にハンダ付けします。

▼ ピンセットとの比較


普段使う 2.5mm ピッチと違って狭いので、ピンセットとルーペを駆使して隣の穴とブリッジが出来ないよう慎重にハンダ付けしていきました。

▼ 目がショボショボする

LED は 19,000mcd 広角 60 度の素子を使用しました。 輝度を考えると 75,000mcd 狭角 15 度のモノと迷いましたが、横から見える光もあった方が良いと思って広角の方を使います。


▼ あ〜目がショボショボする


PIC から出ている青・白・緑は PICKIT3 で書き込む時に使用するリード線で、書き込み完了後は取り除きます。

▼ う〜ん目がショボショボする


ハンダ付けが全て終わったらガワに組み込んで干渉しない事を確認し、書き込み用のリード線と PICKIT3 とを接続し書き込みを行いました。

▼ この状態で書き込みを行う


プログラムはとてもシンプルです。

電池を入れるとボタンが押されるまでスリープ状態で待機。 ボタンを押すとトリプルフラッシュモード、もう一回押すとランダム・フォーモード、さらにもう一回押すと停止してスリープに移行します。

以下アセンブラリストです。



;*********************************************
;
; 自転車用テールライト 1
;
; 2012/05/26 ver.1(初版)
;
;*********************************************
list p=12f629
#include

__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

; キャリブレーションデータ = 0x1f
;*********************************************

#DEFINE SW_PUSH GPIO,4 ; スイッチ
#DEFINE IO_LEDOUT GPIO,2 ; LED

i EQU 0x20 ;ループカウンタ用変数
j EQU 0x21 ;ループカウンタ用変数
k EQU 0x22 ;ループカウンタ用変数


F_CHAT EQU 0x23
F_MODE EQU 0x24 ; フラッシュモード用変数
; 0 = sleep
; 1 = トリプルフラッシュ
; 2 = ランダムフォー

;---- 割り込み用
w_temp EQU 0x25
status_temp EQU 0x26

ORG 0x000
GOTO INIT

;割り込みハンドラ
ORG 0x004
GOTO INTR

;*********************************************
;初期化開始
INIT
BCF INTCON,GIE ;全割込み禁止

;内部クロック補正
bsf STATUS,RP0 ;BANK=1
call 0x3ff
movwf OSCCAL
bcf STATUS,RP0 ;BANK=0
;割り込みを禁止
clrf INTCON
;コンパレータ使用禁止
movlw 0x07
movwf CMCON

;GPIO 入出力設定
bsf STATUS,RP0 ;BANK=1
movlw b'11111000';GPIO 0/1/2 を出力、4 をスイッチ入力にする
movwf TRISIO

; 内部プルアップ設定
MOVLW B'00000000' ;GPPU=0 プルアップ有効化
MOVWF OPTION_REG
MOVLW B'00010000' ;WPU4=1 GPIO4をプルアップ
MOVWF WPU ;

; ポート変化割り込み許可ポート設定
movlw b'00010000' ;GP4 を状態変化として使用
movwf IOC

bcf STATUS,RP0 ;BANK=0

CLRF F_MODE ; フラッシュモードフラグリセット
CLRF F_CHAT ; チャタリングフラグリセット

; ポート変化割り込み有効、全割り込み有効
movlw b'10001000' ;
movwf INTCON ;

;*********************************************
; メインループ
MAIN_LOOP
; フラッシュモード判断
MOVF F_MODE,W
SUBLW D'0' ; この値からWレジスタの値を引く
BTFSC STATUS,Z ; 0だったらZフラグがセットされる
GOTO SLEEP_MODE ; スリープモードへ移行

MOVF F_MODE,W
SUBLW D'1' ; この値からWレジスタの値を引く =1?
BTFSC STATUS,Z ; 0だったらZフラグがセットされる
GOTO FLASH_TRIPLE ; トリプルフラッシュモードへ

MOVF F_MODE,W
SUBLW D'2' ; この値からWレジスタの値を引く =2?
BTFSC STATUS,Z ; 0だったらZフラグがセットされる
GOTO FLASH_RANDOMFOUR ; ランダムフォーフラッシュモードへ

GOTO MAIN_LOOP

; スリープモード
SLEEP_MODE
SLEEP ; スリープモード移行
NOP
GOTO MAIN_LOOP

;*********************************************
FLASH_TRIPLE ;トリプルフラッシュ
BSF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BCF IO_LEDOUT
movlw d'66' ;66ms遅延
movwf i
call DELAYms

BSF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BCF IO_LEDOUT
movlw d'66' ;66ms遅延
movwf i
call DELAYms

BSF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BCF IO_LEDOUT
movlw d'250' ;トータル594ms遅延
movwf i
call DELAYms
movlw d'250'
movwf i
call DELAYms
movlw d'160'
movwf i

GOTO MAIN_LOOP

FLASH_RANDOMFOUR ;ランダムフォー
BSF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BCF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BSF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BCF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BSF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BCF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BSF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BCF IO_LEDOUT
movlw d'165' ;165ms遅延
movwf i
call DELAYms

BSF IO_LEDOUT
movlw d'99' ;99ms遅延
movwf i
call DELAYms

BCF IO_LEDOUT
movlw d'132' ;132ms遅延
movwf i
call DELAYms

BSF IO_LEDOUT
movlw d'33' ;33ms遅延
movwf i
call DELAYms

BCF IO_LEDOUT
movlw d'165' ;165ms遅延
movwf i
call DELAYms

GOTO MAIN_LOOP

;*********************************************
;ミリ秒遅延ルーチン(1ms 〜 254ms まで)
;内部発振モード4Mhz用
;1命令サイクル = 1/4 クロック = 1x10^6 = 1/1,000,000 = 1μS

DELAYms: ;ix1000サイクル
CLRW ;Wをクリア
ADDWF i,W ;メインルーチンでのミリ秒設定値 i を
MOVWF j ;ループカウンタ j にセットする
;---------------------------
DELAY1k: ;1000サイクルの遅延ループ
MOVLW d'249' ;ループカウンタkに249をセットする
MOVWF k
LOOP1k:
NOP
DECFSZ k,f
GOTO LOOP1k ;2+4x249-1
;---------------------------
DECFSZ j,f ;3xj+997xj=1,000xj
GOTO DELAY1k
RETURN ;メインルーチンに戻る

;*****************************************
; 割り込み処理
;*****************************************
INTR
; 割り込み前処理
MOVWF w_temp ;Wレジスタ退避
MOVF STATUS,w ;STATUS取り出し
MOVWF status_temp ;STATUS退避

;割り込み処理開始 -------------------------

BTFSC SW_PUSH ; スイッチが押された時だけ以下の処理を行う
GOTO INTR_END

; チャタリング回避処理
movlw d'10' ;10ms遅延
movwf i
call DELAYms

BTFSC SW_PUSH ; スイッチが押された時だけ以下の処理を行う
GOTO INTR_END

INCF F_MODE,F ; SWフラグ+1
MOVF F_MODE,W

SUBLW D'3' ; この値からWレジスタの値を引く
BTFSC STATUS,Z ; 0だったらZフラグがセットされる
CLRF F_MODE ; フラグリセット


INTR_END
; 割り込み後処理
MOVF status_temp,w ;STATUSを戻す
MOVWF STATUS ;
SWAPF w_temp,f ;Wレジスタを戻す
SWAPF w_temp,w ;

BCF INTCON,GPIF ; ピン変化割込みフラグクリア

RETFIE

END

トリプルフラッシュとランダムフォーの点滅パターンについてはもう何度も書いているので説明しません。

問題なく動作する事を確認したら書き込みのためのリード線を切断します。

エネループを入れる

元通りにカバーをはめて完成です。

▼ 完成!



実際に自転車に装着して点灯テストしました。

▼ 装着し点灯させる

動画ではランダムフォーの点滅パターンが分かりにくいですね。

他の人の緊急自動車を撮影した映像を見ると、夜間でも明るく点灯パターンが綺麗に見えるのですが、あれってどういう設定でやってるんでしょう?