テールライトが見付かる

先日、気付いたら無くなっていたというテールライトですが、気落ちしながらも新作を作っていたら見付かったんです。


夜 8 時頃帰宅したら玄関脇で「ん? 何かピカピカ点滅するモノが・・・アレ!?」 と近づくと無くしたと思っていたテールライトでした。 なんでこんな所に!?と不思議です。

▼ 玄関脇で雨の中でピカピカ光るテールライト

中を開けてみると昨日今日の雨は内部に浸透し水と泥で悲惨でしたが、ボタンを押すと機能したのが意外です。

▼ 電池端子も基板の銅箔もサビてしまっている


新しいほうはいったん保留して、プログラムをバージョンアップする事にします。 高速トリプルフラッシュモードの追加とスイッチチャタリングの除去です。


;*********************************************
;
; 自転車用テールライト 4
;
; 2012/07/06 ver.1.3 ノーマルフラッシュを止めて高速トリプルフラッシュモード追加、SWチャタリング除去
; 2012/06/20 ver.1.2 ノーマルフラッシュモード機能追加
; 2012/06/19 ver.1.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

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

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

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

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

TMR_COUNTER EQU 0x25 ; タイマーカウンター変数


;---- 割り込み用
w_temp EQU 0x30
status_temp EQU 0x31

; スイッチチャタリング
F_CHAT EQU 0x35 ;

ORG 0x000
GOTO INIT

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

;*********************************************
;初期化開始
INIT
CLRF INTCON ;全割込み禁止

;内部クロック補正
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

; /OPTION_REG 設定
; GPPU=0 内部プルアップ有効化
; ピン変化は立下りで割り込み
MOVLW B'00000000' ;
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 ; フラッシュモードフラグリセット

MOVLW D'3'
MOVWF F_CHAT ; チャタリングカウンタセット

; LED 消灯
BCF IO_LEDOUT

BSF INTCON,GPIE ; ポート変化割込み許可
BSF INTCON,GIE ; 全割込み許可

;*********************************************
; メインループ
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_RANDOMFOUR ; ランダムフォーモードへ

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

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

GOTO MAIN_LOOP

; スリープモード
SLEEP_MODE
SLEEP ; スリープモード移行
NOP
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

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_TRIPLE_HI
BSF IO_LEDOUT
movlw d'42' ;42ms遅延
movwf i
call DELAYms

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

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

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

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

BCF IO_LEDOUT
movlw d'167' ;167ms遅延
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
BCF INTCON,7 ; 二重割り込みを禁止

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

BTFSS INTCON,GPIF ; 発生源がピン変化割り込み?
GOTO INTR_END

; スイッチ入力割り込み処理開始 -------------------------
INTR_SW_CHANGE
; ウェイト(少し多め)
movlw d'50'
movwf i
call DELAYms

; SWが離されるまで待機
BTFSS SW_PUSH
GOTO INTR_SW_CHANGE

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

; LED 消灯
BCF IO_LEDOUT

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

SUBLW D'4' ; この値から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 ;

BSF INTCON,7 ; 割り込み再許可

RETFIE

END

消灯状態からボタンを押していくと「ランダムフォー」→「トリプルフラッシュ」→「高速トリプルフラッシュ」→ 消灯 という風に動作します。

高速トリプルフラッシュというのは、LED ハイメディック救急車の後部にある警光灯の点滅パターンの事です。

▼ この部分の事


▼ テスト風景をどうぞ

実際にこれを点灯させて何度か走ってみましたが、振動で誤動作する事もまた脱落する事も無く、自分では見る事は出来ないですけど後方で非常に目立っていると思います。