2026年4月12日日曜日
アメリカからのアクセス急増は継続中
2026年4月5日日曜日
見守りセンサは保留、休養日
写真の風景について
満開の桜(ソメイヨシノでしょうか)と、うっすらとした青空を背景にしたひつじ雲のコントラストがとても綺麗ですね。高積雲は太陽の光を通しにくいため、このように少し落ち着いた色味の空模様を作り出します。
今のところはまだ日差しが届いていますが、もしこの雲が厚くなってきたら、傘の準備を考えておくと安心かもしれません。
2026年4月1日水曜日
LINEに通知する見守りセンサ、最終テスト継続中
日曜日から開始したLINE見守りセンサは、普段使っていない部屋に置いてあり、見守り継続中です。昨日はその部屋に入るのが遅れてしまい、15時間無反応が検出されてしまいました。うまく動いていることが確認できたのでOKです。
今日は、毎月1日の12:00に見守り継続中であることを知らせる通知機能が無事に動作して、メッセージが届きました。職場で昼休みに確認して小さくガッツポーズ。LINEのトーク画面に桜の花びらが舞っています。
あとは、外出(旅行)スイッチが押されたあと、帰宅反応があるまで見守りを保留する機能と、帰宅しなくても4日経過すると見守りが自動復帰する機能の確認をしていきます。自動復帰は4日後(24Hx4)にしていますが、自動復帰からさらに15時間反応がなかったときにメッセージが飛びます。計111時間後ですね。このあたりを確認し、一通りの検証が終わったらスケッチと回路図をアップするつもりです。
ちなみに、ESP32開発キットを使ったプロトタイプのスケッチは以下にあります。機能的にはほぼ同じ。
- LINEに通知する見守りセンサ(その2;プロトタイプ) (2025年8月24日)
早いところ仕上げないと1年がかりのプロジェクトになってしまう。
2026年3月29日日曜日
LINEに通知する見守りセンサの最終テスト開始
急に暖かくなってお花見日和でした。しかし相変わらず花粉症が酷いので、遠出は避けて近所で軽くお花見。
今朝、見守りセンサに最終プログラムを書き込み、テストしようとしたら動作中を示す緑色LEDが点灯しません。プログラムの不具合かと調べましたが明らかに光るはず。基板の裏からLED接続箇所をテスタで測ったら異常です。念のためLEDテスタで電圧をかけてみましたが点灯しません。ユニバーサル基板に繋いだのは新しいLEDだったと思うのですが、壊れていたようです。滅多にないです。
ということで朝からLEDを交換してようやく長時間のテスト開始。主に以下の内容を確認します。
- 15時間反応がないとLINEにメッセージが飛ぶ。15時間以内にセンサの前を横切るとカウンタをリセットする
- 外出(旅行)スイッチを押しても4日以上経過すると見守りを再開する。よって4日+15時間でメッセージが飛ぶ
- 毎月1日の12:00に見守り継続中である旨のメッセージが飛ぶ。
見守り開始時に飛んできたメッセージ。
2026年3月28日土曜日
TOFセンサ近接スイッチでオンオフするLED照明(完成)
TOFセンサを使った近接スイッチでLED照明のオンオフを行う工作もいよいよ大詰め。
先日届いた小型の電源モジュール にAC100Vを繋いで動作確認したら全然電圧がでません。壊れているのかと思い、もう1個調べても同じ。調べてみると購入したショップの商品説明には記載がなかったのですが、他のショップの説明欄を見ると、外付けに耐圧の大きなコンデンサ(物理的にも大きくなる)が必要なことが判りました。これでは小さく作れません。トホホです。
諦めて当初の計画通りトランスレス電源で行くことにしました。TOFセンサが発光するタイミングで電位が下がるため、モニタ用に点灯させている白色LEDがチラチラします。そこで白色LEDはやめて緑色にしたら若干目立たなくなったのでOKとしました。
写真はLED照明の端カバーに基板を収めた様子です。照明の拡散カバーの切り欠きはTOFセンサと干渉するためカットした跡です。
プログラム(PIC アセンブラ)です。こちらも無保証です。著作権等は留保しますが、流用・改造などご自由にどうぞ。
;---------------------------------------------------------------------
; TOF近接センサVL6180Xを使った非接触スイッチ
;
; 2026.02.22 naka
; 1. 概要
; 近接センサの前で手をかざすとオンオフ動作するスイッチ
; ・距離は180mm位まではOK(動作確認時190mm程度までは反応した)#defineで設定
; ・スイッチ動作はオルタネート(一度近づくとオン、一旦離れてもう一度でオフ)
; ・距離測定は0.1秒毎、オンオフ動作時は1秒後に確認(チャタリング的な動作を避けるため)
;
; 2. ピンアサイン
;
; (1). GP0 [in] : (ICSP DAT)
; (2). GP1 [in] : (ICSP CLK)
; (3). GP2 [out]: LED(デバッグ時に使用;最終的にSSRに置き換える)
; (4). GP3 [in] : (ICSP VPP)
; (5). GP4 [in] : I2C SDA
; (6). GP5 [in] : I2C SCL
;
; 3. 備考
; ・動作クロック :内蔵OSC 4MHz
; ・電源 :3V(TOFセンサが2.8-3.0Vなので)
; ・I2Cの応答待ちなどによる無限ループ対策にWDTを利用
;
; 4. 改版履歴
; 2026.02.14 new
; 2026.02.22 色々修正
;
;---------------------------------------------------------------------
;---------------------------------------------------------------------
; デバイス定義
;---------------------------------------------------------------------
LIST P=12F629
INCLUDE <P12F629.INC>
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _BODEN_OFF & _CP_OFF
ERRORLEVEL -302 ;アセンブル時のバンク警告メッセージ抑制
;---------------------------------------------------------------------
; ピン定義
;---------------------------------------------------------------------
#define LED 2
#define SDA 4
#define SCL 5
;---------------------------------------------------------------------
; TOFセンサ VL6180X I2Cアドレス
;---------------------------------------------------------------------
#define TOFADDR 0x52
;---------------------------------------------------------------------
; TOFセンサが反応する距離(mm) これより近いとオン/オフする
;---------------------------------------------------------------------
#define ACTDIST D'180'
;---------------------------------------------------------------------
; 変数レジスタの定義
;---------------------------------------------------------------------
WAIT1 EQU H'20'
WAIT2 EQU H'21'
CNT1 EQU H'22'
CNT2 EQU H'23'
OFFSET EQU H'24'
RANGE EQU H'25'
TIMOUTH EQU H'26'
TIMOUTL EQU H'27'
TOGGLE EQU H'28' ; 0ビット:トグル、1ビット:前回状態
; H'40'からI2C通信に利用(下の方で定義)
;
;---------------------------------------------------------------------
; マクロ
;---------------------------------------------------------------------
; TOFセンサ8ビットレジスタ設定
REG8BIT MACRO IDXH,IDXL,DATA
RETLW IDXH
RETLW IDXL
RETLW DATA
ENDM
; TOFセンサ16ビットレジスタ設定
REG16BIT MACRO IDXH,IDXL,DATAH,DATAL
RETLW IDXH
RETLW IDXL
RETLW DATAH
RETLW DATAL
ENDM
;
; TOFセンサレジスタ書き込み
WTREG MACRO HIGH,LOW,DATA
MOVLW TOFADDR
CALL I2CWSTART
MOVLW HIGH
MOVWF datao
CALL TX
MOVLW LOW
MOVWF datao
CALL TX
MOVLW DATA
MOVWF datao
CALL TX
CALL I2CSTOP
ENDM
RDREG MACRO HIGH,LOW
MOVLW TOFADDR
CALL I2CWSTART
MOVLW HIGH
MOVWF datao
CALL TX
MOVLW LOW
MOVWF datao
CALL TX
CALL I2CSTOP
;
MOVLW TOFADDR
CALL I2CRSTART
CALL RX
CALL I2CSTOP
ENDM
;
;---------------------------------------------------------------------
; リセットベクタ
;---------------------------------------------------------------------
ORG 00H ; リセット時の飛び込み先
GOTO MAIN ;
;
ORG 04H ; 割り込み時の飛び込み先
;---------------------------------------------------------------------
; 割り込み処理
;---------------------------------------------------------------------
INTRUPT
RETFIE
;---------------------------------------------------------------------
; メイン処理
;---------------------------------------------------------------------
MAIN
CALL DEVINIT
;
CALL VL6180INIT
CALL VL6180CONFIG
;
CLRF TOGGLE
;
MAIN_LP
CLRF RANGE
CALL READRANGE ; 測定
;
MOVF RANGE,W
SUBLW ACTDIST ; アクティブか否かチェック
BTFSS STATUS,C
GOTO INACT
; 前回もアクティブなら何もしない(そうしないと点滅する)
BTFSC TOGGLE,1
GOTO NEXTREAD
BSF TOGGLE,1 ; 前回アクティブではないのでトグル動作
GOTO TOGGLESW
;
INACT
BCF TOGGLE,1
GOTO NEXTREAD
TOGGLESW
MOVF TOGGLE,W
XORLW H'01'
MOVWF TOGGLE
;
BTFSS TOGGLE,0
GOTO $+3
BSF GPIO,LED
GOTO $+2
BCF GPIO,LED
;
CALL W05S ; トグル動作時は1秒待つ
CALL W05S
GOTO MAIN_LP
;
NEXTREAD
CALL W100MS ; 100ミリ秒ごとに測定
CLRWDT
GOTO MAIN_LP
;
;---------------------------------------------------------------------
; 初期化
;---------------------------------------------------------------------
DEVINIT
CLRF INTCON ;全割込み禁止
;
BANKSEL CMCON
MOVLW B'00000111' ; GP0-2をデジタルI/Oに設定
MOVWF CMCON ; デフォルトはコンパレータ
; BANKSEL 1
; CALL 3FFH ; 内部OSCのキャリブレーションデータ
; MOVWF OSCCAL ; OSCCALレジスタにセット
BANKSEL TRISIO
MOVLW B'00000011' ; RA0,RA1 input
MOVWF TRISIO
BANKSEL GPIO
;
BANKSEL 0
CLRWDT ; Clear WDT
CLRF TMR0 ; Clear TMR0
;
BANKSEL OPTION_REG
MOVLW b'00101101' ; WDTプリスケーラ 1:32 (576ms)
MOVWF OPTION_REG
BANKSEL 0
;
BCF GPIO,LED
;
RETURN
;
;---------------------------------------------------------------------
; VL6180レジスタindex (#define名は32文字まで)
;---------------------------------------------------------------------
#define READOUT__AVERAGING_SAMPLE_PERIOD 0x01,0x0A
#define SYSALS__ANALOGUE_GAIN 0x00,0x3F
#define SYSALS__INTEGRATION_PERIOD 0x00,0x40
#define SYSALS__INTERMEASUREMENT_PERIOD 0x00,0x3E
#define SYSRANGE__VHV_REPEAT_RATE 0x00,0x31
#define SYSRANGE__VHV_RECALIBRATE 0x00,0x2E
#define SYSRANGE__INTERMEASUREMENT_PERIO 0x00,0x1B
#define SYSRANGE__MAX_CONVERGENCE_TIME 0x00,0x1C
#define SYSTEM__INTERRUPT_CONFIG_GPIO 0x00,0x14
#define SYSTEM__INTERRUPT_CLEAR 0x00,0x15
#define INTERLEAVED_MODE__ENABLE 0x02,0xA3
#define RESULT__RANGE_STATUS 0x00,0x4D
#define RESULT__INTERRUPT_STATUS_GPIO 0x00,0x4F
#define SYSRANGE__START 0x00,0x18
#define RESULT__RANGE_VAL 0x00,0x62
;
;---------------------------------------------------------------------
; VL6180初期化(メモリ節約のためベタ書きではなくループを回した)
;---------------------------------------------------------------------
VL6180INIT
CLRF OFFSET
CALL REG8BITDT
MOVWF CNT1 ; 設定パラメタ数
VLINIT_LP1
MOVLW H'52' ; アドレス
CALL I2CWSTART
MOVLW D'3' ; indexHigh, indexLow, data の3バイトを送る
MOVWF CNT2
VLINIT_LP2
INCF OFFSET,F
CALL REG8BITDT
MOVWF datao
CALL TX ; I2C送信
DECFSZ CNT2,F
GOTO VLINIT_LP2
;
CALL I2CSTOP
;
DECFSZ CNT1,F
GOTO VLINIT_LP1
;
RETURN
REG8BITDT ; 以下のテーブルから順に取り出す
ORG H'100'
MOVLW H'01'
MOVWF PCLATH
MOVF OFFSET,W
ADDWF PCL,F
RETLW D'31' ; 31パラメタ
REG8BIT 0x02,0x07,0x01 ; indexHigh, indexLow, data
REG8BIT 0x02,0x08,0x01
REG8BIT 0x00,0x96,0x00
REG8BIT 0x00,0x97,0xFD ; RANGE_SCALER = 253
REG8BIT 0x00,0xE3,0x01
REG8BIT 0x00,0xE4,0x03
REG8BIT 0x00,0xE5,0x02
REG8BIT 0x00,0xE6,0x01
REG8BIT 0x00,0xE7,0x03
REG8BIT 0x00,0xF5,0x02
REG8BIT 0x00,0xD9,0x05
REG8BIT 0x00,0xDB,0xCE
REG8BIT 0x00,0xDC,0x03
REG8BIT 0x00,0xDD,0xF8
REG8BIT 0x00,0x9F,0x00
REG8BIT 0x00,0xA3,0x3C
REG8BIT 0x00,0xB7,0x00
REG8BIT 0x00,0xBB,0x3C
REG8BIT 0x00,0xB2,0x09
REG8BIT 0x00,0xCA,0x09
REG8BIT 0x01,0x98,0x01
REG8BIT 0x01,0xB0,0x17
REG8BIT 0x01,0xAD,0x00
REG8BIT 0x00,0xFF,0x05
REG8BIT 0x01,0x00,0x05
REG8BIT 0x01,0x99,0x05
REG8BIT 0x01,0xA6,0x1B
REG8BIT 0x01,0xAC,0x3E
REG8BIT 0x01,0xA7,0x1F
REG8BIT 0x00,0x30,0x00
REG8BIT 0x00,0x16,0x00 ;SYSTEM__FRESH_OUT_OF_RESET
;
;---------------------------------------------------------------------
; VL6180 configureDefault
;---------------------------------------------------------------------
VL6180CONFIG
CLRF OFFSET
CALL CONFIGDT
MOVWF CNT1 ; 設定パラメタ数
VLCONFIG_LP1
MOVLW H'52' ; アドレス
CALL I2CWSTART
MOVLW D'3' ; indexHigh, indexLow, data の3バイトを送る
MOVWF CNT2
VLCONFIG_LP2
INCF OFFSET,F
CALL CONFIGDT
MOVWF datao
CALL TX ; I2C送信
DECFSZ CNT2,F
GOTO VLCONFIG_LP2
;
CALL I2CSTOP
;
DECFSZ CNT1,F
GOTO VLCONFIG_LP1
;
; テーブルのラストにある16bitパラメタ1個のみ
MOVLW D'4' ; indexHigh, indexLow, dataHigh, dataLow の4バイトを送る
MOVWF CNT2
VLCONFIG_LP3
INCF OFFSET,F
CALL CONFIGDT
MOVWF datao
CALL TX ; I2C送信
DECFSZ CNT2,F
GOTO VLCONFIG_LP3
;
CALL I2CSTOP
;
RETURN
;
CONFIGDT ; 以下のテーブルから順に取り出す
MOVLW H'01'
MOVWF PCLATH
MOVF OFFSET,W
ADDWF PCL,F
RETLW D'9' ; 8bit 9パラメタ + 16bit 1パラメタ
REG8BIT READOUT__AVERAGING_SAMPLE_PERIOD,0x30
REG8BIT SYSALS__ANALOGUE_GAIN,0x46
REG8BIT SYSRANGE__VHV_REPEAT_RATE,0xFF
REG8BIT SYSRANGE__VHV_RECALIBRATE,0x01
REG8BIT SYSRANGE__INTERMEASUREMENT_PERIO,0x09 ; 100ms
REG8BIT SYSALS__INTERMEASUREMENT_PERIOD,0x31 ; 500ms
REG8BIT SYSTEM__INTERRUPT_CONFIG_GPIO,0x24
REG8BIT SYSRANGE__MAX_CONVERGENCE_TIME,0x31 ; 49ms
REG8BIT INTERLEAVED_MODE__ENABLE,0x00
REG16BIT SYSALS__INTEGRATION_PERIOD,0x00,0x63 ; 16bitパラメタ(1個のみ)
;
;---------------------------------------------------------------------
; VL6180 readRange
;---------------------------------------------------------------------
READRANGE
; デバイスがreadyになるまで待つ
RDREG RESULT__RANGE_STATUS
MOVF datai,W
ANDLW H'01'
BTFSC STATUS,Z
GOTO READRANGE
;
; 測定開始フラグ設定
WTREG SYSRANGE__START,0x01
;
CLRF TIMOUTH ; タイムアウトカウント用
CLRF TIMOUTL
READRANGLP
CALL CHKTIMEOUT ; タイムアウト確認
BTFSS STATUS,Z
GOTO READRANGE2
MOVLW D'255' ; タイムアウト
MOVWF RANGE
RETURN
;
READRANGE2
; 測定完了確認
RDREG RESULT__INTERRUPT_STATUS_GPIO
MOVF datai,W
ANDLW 0x07
SUBLW 0x04
BTFSS STATUS,Z
GOTO READRANGLP
;
; 値を読み出す
RDREG RESULT__RANGE_VAL
MOVF datai,W
MOVWF RANGE
;
; 割り込みフラグクリア
WTREG SYSTEM__INTERRUPT_CLEAR, 0x01
;
RETURN
;
;---------------------------------------------------------------------
; センサのタイムアウトチェック(500ms)
; 1回の測定にざっと200usかかるとして 500ms/200us ... TIMOUTH=10
;---------------------------------------------------------------------
CHKTIMEOUT
MOVF TIMOUTL,W
ADDLW D'1'
MOVWF TIMOUTL
BTFSS STATUS,Z
RETURN
;
MOVF TIMOUTH,W
ADDLW D'1'
MOVWF TIMOUTH
SUBLW D'10' ; Zフラグを持ってリターン
RETURN
;
;---------------------------------------------------------------------
; ウェイト色々
;---------------------------------------------------------------------
W1MS
MOVLW D'110'
MOVWF WAIT1
W1MSLP
GOTO $+1
GOTO $+1
GOTO $+1
DECFSZ WAIT1,F
GOTO W1MSLP
GOTO $+1
GOTO $+1
NOP
RETURN
;
W100MS
MOVLW D'100'
MOVWF WAIT2
W100MSLP
CALL W1MS
DECFSZ WAIT2,F
GOTO W100MSLP
CLRWDT
RETURN
;
W05S
CALL W100MS
CALL W100MS
CALL W100MS
W200MS CALL W100MS
CALL W100MS
RETURN
;
;---------------------------------------------------------------------
; I2Cアクセスルーチン
; 流用元:Microchip Applicatin Note : AN982
; Interfacing I2C Serial EEPROMs to PIC10 and PIC12 Drivers
;---------------------------------------------------------------------
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Filename: i2c_routines.inc
; Date: March 21, 2005
; File Version: 1.0
; Assembled using: MPLAB IDE 7.00.00.0
;
; Author: Chris Parris
; Company: Microchip Technology, Inc.
;
;*******************RAM register definitions**********************
#define STARTRAM 0x40 ; Start RAM at address 0x40
cblock STARTRAM
buffer ; Transfer/Receive bit buffer
datai ; Data input byte buffer
datao ; Data output byte buffer
bitcount ; Bit loop counter
bytecount ; Byte loop counter
addressH ; Word address pointer
addressL ; Word address pointer
loops ; Delay loop counter
loops2 ; Delay loop counter
pollcnt ; Polling loop counter
i2caddr
endc
;*******************Bit definitions*******************************
DO equ 0 ; TX/RX buffer output bit
DI equ 1 ; TX/RX buffer input bit
ACKB equ 2 ; ACK/NO ACK select bit
;*******************Delay Macros**********************************
; Each macro delay for 1 inst. cycle less than
; required, as the instruction immediately
; before the macro call provides 1 inst. cycle.
;*****************************************************************
THIGH macro ; Clock high time delay (5 us)
goto $+1 ; 2-inst. cycle delay (2 us)
goto $+1 ; 2-inst. cycle delay (2 us)
nop ; 1us
endm
THDSTA macro ; Start condition hold time delay (5 us)
goto $+1 ; 2-inst. cycle delay (2 us)
goto $+1 ; 2-inst. cycle delay (2 us)
nop ; 1us
endm
TSUSTA macro ; Start condition setup time delay (5 us)
goto $+1 ; 2-inst. cycle delay (2 us)
goto $+1 ; 2-inst. cycle delay (2 us)
nop ; 1us
endm
TSUSTO macro ; Stop condition setup time delay (5 us)
goto $+1 ; 2-inst. cycle delay (2 us)
goto $+1 ; 2-inst. cycle delay (2 us)
nop ; 1us
endm
TAA macro ; Output valid from clock delay (4 us)
goto $+1 ; 2-inst. cycle delay (2 us)
goto $+1 ; 2-inst. cycle delay (2 us)
endm
;-------------------------------------------------------------------
; I2Cアクセス
;-------------------------------------------------------------------
I2CWSTART
MOVWF i2caddr ; I2Cアドレス退避
call BSTART ; Generate start bit
; Now send the control byte
; for a write, to set address
movf i2caddr,W ; I2Cアドレス
movwf datao ; Copy control byte to buffer
call TX ; Output control byte to device
RETURN
I2CSTOP
CALL NOACK
call BSTOP ; Generate stop bit
RETURN
;
I2CRSTART
IORLW H'01'
MOVWF i2caddr ; I2Cアドレス退避
call BSTART ; Generate start bit
; Now send the control byte
; for a write, to set address
movf i2caddr,W
movwf datao ; Copy control byte to buffer
call TX ; Output control byte to device
RETURN
;*******************Start bit subroutine**************************
; This routine generates a Start condition
; (high-to-low transition of SDA while SCL
; is still high.
;*****************************************************************
BSTART
bsf GPIO,SCL ; Make sure SCL is high
TSUSTA ; Start condition setup time delay
BANKSEL 1
BCF TRISIO,SDA ; Configure SDA to be an output
BANKSEL 0
bcf GPIO,SDA ; Pull SDA low to initiate
; Start condition
THDSTA ; Start condition hold time delay
bcf GPIO,SCL ; Bring SCL low in preparation
; for data transfer
BANKSEL 1
BSF TRISIO,SDA ; Configure SDA to be an input
BANKSEL 0
retlw 0
;*******************Stop bit subroutine***************************
; This routine generates a Stop condition
; (low-to-high transition of SDA while SCL
; is still high.
;*****************************************************************
BSTOP
BANKSEL 1
BCF TRISIO,SDA ; Configure SDA to be an output
BANKSEL 0
bcf GPIO,SDA ; Pull SDA low
bsf GPIO,SCL ; Make sure SCL is high
TSUSTO ; Stop condition setup time delay
BANKSEL 1
BSF TRISIO,SDA ; Configure SDA to be an input
BANKSEL 0
retlw 0
;*******************Bit output subroutine*************************
; This routine outputs bit 'DO' in 'buffer' to
; the serial EEPROM device.
;*****************************************************************
BITOUT
bcf GPIO,SCL ; Make sure SCL is low
btfss buffer,DO ; Check for state of bit to xmit
goto bitlow ; If bit is low, pull SDA low
clockout ; If bit is high, leave SDA high
bsf GPIO,SCL ; Bring SCL high to begin transfer
THIGH ; Clock high time delay
bcf GPIO,SCL ; Bring SCL low again
BANKSEL 1
BSF TRISIO,SDA ; Configure SDA to be an input
BANKSEL 0
retlw 0
bitlow
BANKSEL 1
BCF TRISIO,SDA ; Configure SDA to be an output
BANKSEL 0
bcf GPIO,SDA ; Pull SDA low
goto clockout
;*******************Bit input subroutine**************************
; This routine inputs a bit of data from the
; serial EEPROM device, and stores it in bit
; 'DO' of 'buffer'.
;*****************************************************************
BITIN
bcf GPIO,SCL ; Make sure SCL is low
BANKSEL 1
BSF TRISIO,SDA ; Configure SDA to be an input
BANKSEL 0
bsf buffer,DI ; Assume input bit is high
bsf GPIO,SCL ; Bring SCL high to begin transfer
TAA ; Output valid from clock delay
btfss GPIO,SDA ; Check for state of SDA bit
bcf buffer,DI ; If SDA is low, set bit low
bcf GPIO,SCL ; Bring SCL low again
retlw 0
;*******************Data transmit subroutine**********************
; This routine transmits the byte of data
; stored in 'datao' to the serial EEPROM
; device. Instructions are also in place
; to check for an ACK bit, if desired.
; Just replace the 'goto' instruction,
; or create an 'ackfailed' label, to provide
; the functionality.
;*****************************************************************
TX
movlw .8
movwf bitcount ; Initialize loop counter to 8
txlp
bsf buffer,DO ; Assume output bit is high
btfss datao,7 ; Check state of next output bit
bcf buffer,DO ; If low, set buffer bit low
call BITOUT ; Call routine to output bit
rlf datao,F ; Rotate datao left for next bit
decfsz bitcount,F ; Decrement counter, check if done
goto txlp ; Keep looping
CALL ACK
retlw 0
;*******************Data receive subroutine***********************
; This routine reads in one byte of data from
; the serial EEPROM device, and stores it in
; 'datai'. It then responds with either an
; ACK or a NO ACK bit, depending on the value
; of 'ACKB' in 'buffer'.
;*****************************************************************
RX
clrf datai ; Clear input buffer
movlw .8
movwf bitcount ; Initialize loop counter to 8
bcf STATUS,C ; make sure carry bit is low
rxlp
rlf datai,F ; Rotate datai 1 bit left
call BITIN ; Read a bit
btfsc buffer,DI
bsf datai,0 ; Set bit 0 if necessary
decfsz bitcount,F ; 8 bits done?
goto rxlp ; If not, do another
call BITIN ; Call routine to read ACK bit
RETLW 0
ACK
bcf buffer,DO ; If ACKB = 1, send ACK (DO = 0)
call BITOUT ; Send bit
retlw 0
NOACK
bsf buffer,DO ; If ACKB = 1, send ACK (DO = 0)
call BITOUT ; Send bit
retlw 0
;
;---------------------------------------------------------------------
END
;---------------------------------------------------------------------
; 終わり
;---------------------------------------------------------------------
2026年3月25日水曜日
シエラレオネから届いた荷物
先週末はイベントがあって、三連休+1日年次休暇の四連休にしましたが工作の進捗はなく、平日に 見守りセンサのプログラムを修正 したりしていました。一応書けたけどテストはまだ。
そんな中、シエラレオネから国際郵便が届きました。聞いたことあるけど何処だっけ?
2026年3月14日土曜日
USBシリアルアダプタでのESP32-C3へのプログラム書き込み
前回書いたESP32-C3-ROOMSにプログラムが書き込めなかった件 に対応するためbootモードを切り替えるピンをGPIO0からGPIO9に変更しました。しかし書き込めない。
ESP32-C3 Technical Reference Manual を参照したらJoint Download Boot mode(USB-Serial-JTAG)のときは、GPIO9をLowにして、かつGPIO8をHighにする必要があった。最初から確認しておけよ>自分
- BOOTボタン押す(ESP32-WROOMはGPIO0;ESP32-C3はGPIO9だった)
- RESET(EN)押す
- RESET離す
- BOOT離す
- 書き込み
2026年3月8日日曜日
LINEに通知する見守りセンサを仕上げる(まだ未完)
日に日に暖かくなってきてそろそろ梅の花が終わり、まもなく桜の季節です。出かけたりするにはよい気候になりました。しかし、花粉症が酷くてこのところの週末は家に引き籠っています。
昨日まで作っていた LED照明の非接触スイッチ は、電源モジュールが届くまで保留です。今日は昨年作った LINEに通知する見守りセンサのプロトタイプ をユニバーサル基板に載せて、ケース加工まで行いました。
ESP32はプロトタイプから変更して、ピン数の少ない小型のESP32-C3-WROOM-02です。初めて使います。
- BOOTボタン押す(GPIO9=LOW)
- RESET(EN)押す
- RESET離す
- BOOT離す
- 書き込み
2026年3月7日土曜日
TOFセンサを使った非接触スイッチ、電源トラブル
トラブルの発見は、SSRのコントロール用LEDと逆向きにパイロット用白色LEDを繋いでいたのですが、この白色LEDがチラチラ点滅していたことで気付いた。実際には消えてないのですが、電位がパルス状に0.1V位上下しているので点滅のように見えます。
オシロで電源電位を見てみると、TOFセンサがアクティブになると電位が下がって、かつ波打っていました。原因はトランスレス電源の電源容量が足りないとだと推測。TOFセンサはセンス時にレーザ光を発するために断続的に比較的大きな電流が流れます。このため電源電圧が不安定だったようです。
白色LEDの光度だけの問題で、SSRの動作には影響ないようでしたが、念のため電源部の電解コンデンサを200μFから470μF×3個の1,410μFに増量しました。場所がなくてダイオードブリッジとPICの上に寝かせています。それでも白色LEDのチラチラは治まらない。3.1V~3.2V位で波打っていたので白色LEDの順方向電圧に近くて目立ったのだと思う。
最終的に白色LEDは別系統で100Vに繋ぐことにしました。100KΩ抵抗を直列に入れて、LEDとは逆向きのダイオードも入れてます。常時点灯してしまうのと50Hzでチラチラしますが妥協です。
今回、LED照明の端っこのカバーに内蔵するのでスペース的に余裕がなくてトランスレス電源にしましたが、ちゃんとAC100VからDC 3Vを出力する電源モジュールを使ったほうがよいです。
と、ここまで書いてアリエクで薄型の小型電源モジュールを見つけました。ギリギリ収まりそうなので注文。送料が安くて国際郵便だと思うので到着までしばらくかかりそう。また、これを使うとヒューズが収まりそうにないので、ヒューズは外付けします。
2026年3月4日水曜日
TOFセンサによる近接スイッチ WDT実装他
例年になく花粉症が酷くなって、目がしょぼしょぼしています。鼻も詰まって十分な睡眠が取れてない。今日は会議で眠気を抑えるのが大変でした。以前も書いたけど、日本中で生産性が落ちて経済損失になっているのではないかと思う。
夕食後しょぼしょぼ目の状態でパソコンを睨んで、TOFセンサを使った近接スイッチ(非接触スイッチ)のプログラムを見直しました。
ひとつはWDT(ワッチドッグタイマ)による無限ループ監視です。I2Cをソフトで実現しているのと、TOFセンサからの応答が想定外だったりして無限ループする可能性があるので、その対策です。WDTはタイマのカウント溢れにより約18ms毎にリセットがかかるものです。無限ループしていてもリセットで初期状態(プログラムの先頭に飛ぶ)になります。プログラムが正常に動いているときは、カウンタが溢れる前にWDTをクリアするCLRWDT命令を発行することでリセットがかからないようにします。
18msは短いのでプリスケーラを使ってもう少し時間を空けても大丈夫なように調整します。今回、1:32のプリスケーラ設定で18ms x 32 = 576ms以内にWDTをクリアするようにしました。18msの精度はあまり高くないようなので余裕を見て早めにクリアするようにしています。
先週末にPICやTOFセンサはユニバーサル基板に実装しましたが、もう1セットあるのでそちらを使いブレッドボード上でデバッグ中。某ジャンカー界隈では「ジャンクは2個買え」という教えがあるようですが、「部品も2個買え」です。万が一壊れていたときなど、自分が悪いのか部品が悪いのかの切り分けにも必要です。こうして部品が溜まっていく。
プログラムの二つ目の見直しは、小型液晶画面への表示機能の削除です。TOFセンサのデバッグ時に距離を表示していたI2Cで繋ぐ小型液晶は不要なので回路からも外し、プログラムからも削除します。液晶に数字を表示するために組み込んでいたBCD変換(バイナリから2進化10進数変換)のコードを削除したり、表示するコードを削除。これにより変数レジスタもかなり削減されたので整理しました。また、無駄なコードも見直して少しすっきり。
これで週末にはLED照明に組み込める目途は付きました。まだ修正するかも知れないので、ソースの公開はもう少ししてから。
2026年3月1日日曜日
TOFセンサによる近接スイッチのユニバーサル基板実装
花粉症が酷いので外出もせず、昨日のToFセンサによる近接スイッチのLED照明への組み込みの続きです。と言っても昨日は何もしなかったのですが。LED照明のカバー内へ組み込むためにユニバーサル基板に載せてみました。
写真はトランスレス電源が正しく動いているかの確認をしているところです。左の白い2本のコードからAC100Vを供給しています。ツェナーダイオードが手元に3.3Vのものしかなかったので、出力先にシリコンダイオードを直列に入れて少し電圧をドロップさせています。それでもLED程度の負荷で3.2V弱でていました。ToFセンサの定格3Vを若干オーバしていますが、PICやToFセンサを繋げば若干下がることを期待。
トランスレス電源が上手く動いていることが確認できたので、他の部品も載せて基板内の配線まで完了です。基板の中央が空いているのは、ここにLED照明の電源コネクタがくるためです。黄色いコードが出力で、LED照明の電源部に接続します。
2026年2月28日土曜日
TOFセンサによる近接スイッチを照明機器へ組み込む検討
例年のことですが花粉症の症状が酷くなってきました。今週クリニックで薬を処方してもらい、点眼薬も始めたのですが目が痒くて辛い。鼻水のため鼻のかみすぎで鼻の下が赤くなってきてしまった。
そんな中、TOFセンサとPICで作った近接スイッチ を照明機器に組み込む検討を始めました。組み込む前にプログラムを一部改善して、WDT(ワッチドッグタイマ)で無限ループを避けるようにしたいと思っています。I2Cをソフトで実現しているのと、TOFセンサからの応答待ちなど、何らかのタイミングで無限ループしないとも限りません。WDTは時々タイマをリセットしないと、強制的にリセットがかかる(レジスタなどはそのままですが)仕掛けです。デッドマンスイッチのようなもの。
その改善前にLED照明機器に今回のスイッチが組み込めるか検討しています。LED照明はアマゾンで購入したそれほど高価ではないもの。2本購入して1本は納戸に取り付けました。 これをキッチンのシンクの上に取り付けようと考えています。現在はプルスイッチタイプの蛍光灯がついています。
ケーブルの途中に中間スイッチがあって、点灯させると結構明るい。明るすぎてゴーストがでています。
2026年2月22日日曜日
TOFセンサとPICで作った近接スイッチプロトタイプ(動画)
ToFセンサVL6180とPIC12F629を使った近接スイッチのプロトタイプができました。以下、動作の様子、42秒ほどの短い動画です。
点灯している赤色LEDの代わりにSSR(Solid State Relay)を繋ぐことでLED照明のスイッチにします。
以下、ソースコードです。バグがあるかも知れません。無保証です。
VL6180Xの初期化とコンフィグはarduinoライブラリのソースを参考にしていますが、これで十分なのか過剰なのか理解できていません。データシートが英語で87ページもあって全ては読めませんでした。読んでも理解できたか不明ですが。一応動いているようなので趣味で使うにはOKとしてます。
;---------------------------------------------------------------------
; TOF近接センサVL6180Xを使った非接触スイッチ
;
; 2026.02.22 naka
; 1. 概要
; 近接センサの前で手をかざすとオンオフ動作するスイッチ
; ・距離は150mm位まではOK(動作確認時190mm程度までは反応した)#defineで設定
; ・スイッチ動作はオルタネート(一度近づくとオン、一旦離れてもう一度でオフ)
; ・距離測定は0.1秒毎、オンオフ動作時は1秒後に確認(チャタリング的な動作を避けるため)
;
; 2. ピンアサイン
;
; (1). GP0 [in] : (ICSP DAT)
; (2). GP1 [in] : (ICSP CLK)
; (3). GP2 [out]: LED(デバッグ時に使用;最終的にSSRに置き換える)
; (4). GP3 [in] : (ICSP VPP)
; (5). GP4 [in] : I2C SDA
; (6). GP5 [in] : I2C SCL
;
; 3. 備考
; ・動作クロック :内蔵OSC 4MHz
; ・電源 :3V(TOFセンサが2.8-3.0Vなので)
;
; 4. 改版履歴
; 2026.02.14 new
; 2026.02.22 色々修正
;
;---------------------------------------------------------------------
;---------------------------------------------------------------------
; デバイス定義
;---------------------------------------------------------------------
list P=12F629
include <P12F629.INC>
__config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _BODEN_OFF & _CP_OFF
ERRORLEVEL -302 ;アセンブル時のバンク警告メッセージ抑制
;---------------------------------------------------------------------
; ピン定義
;---------------------------------------------------------------------
#define LED 2
#define SDA 4
#define SCL 5
;---------------------------------------------------------------------
; TOFセンサ VL6180X I2Cアドレス
;---------------------------------------------------------------------
#define TOFADDR 0x52
;---------------------------------------------------------------------
; TOFセンサが反応する距離(mm) これより近いとオン/オフする
;---------------------------------------------------------------------
#define ACTDIST D'150'
;---------------------------------------------------------------------
; 変数レジスタの定義
;---------------------------------------------------------------------
WAIT1 EQU H'20'
WAIT2 EQU H'21'
CNT EQU H'22'
TMP EQU H'23'
CNT1 EQU H'24'
CNT2 EQU H'25'
CNT3 EQU H'26'
BUFF EQU H'27' ; 27-2B (LCD 5文字分)
;
binH EQU H'30'
binL EQU H'31'
bcdH EQU H'32'
bcdM EQU H'33'
bcdL EQU H'34'
counter EQU H'35'
temp EQU H'36'
;
OFFSET EQU H'37'
RANGE EQU H'38'
TIMOUTH EQU H'39'
TIMOUTL EQU H'3A'
TOGGLE EQU H'3B' ; 0ビット:トグル、1ビット:前回状態
; H'40'からI2C通信に利用(下の方で定義)
;
;---------------------------------------------------------------------
; マクロ
;---------------------------------------------------------------------
; TOFセンサ8ビットレジスタ設定
REG8BIT MACRO IDXH,IDXL,DATA
RETLW IDXH
RETLW IDXL
RETLW DATA
ENDM
; TOFセンサ16ビットレジスタ設定
REG16BIT MACRO IDXH,IDXL,DATAH,DATAL
RETLW IDXH
RETLW IDXL
RETLW DATAH
RETLW DATAL
ENDM
;
; TOFセンサレジスタ書き込み
WTREG MACRO HIGH,LOW,DATA
MOVLW TOFADDR
CALL I2CWSTART
MOVLW HIGH
MOVWF datao
CALL TX
MOVLW LOW
MOVWF datao
CALL TX
MOVLW DATA
MOVWF datao
CALL TX
CALL I2CSTOP
ENDM
RDREG MACRO HIGH,LOW
MOVLW TOFADDR
CALL I2CWSTART
MOVLW HIGH
MOVWF datao
CALL TX
MOVLW LOW
MOVWF datao
CALL TX
CALL I2CSTOP
;
MOVLW TOFADDR
CALL I2CRSTART
CALL RX
CALL I2CSTOP
ENDM
;
;---------------------------------------------------------------------
; リセットベクタ
;---------------------------------------------------------------------
ORG 00H ; リセット時の飛び込み先
GOTO MAIN ;
;
ORG 04H ; 割り込み時の飛び込み先
;---------------------------------------------------------------------
; 割り込み処理
;---------------------------------------------------------------------
INTRUPT
RETFIE
;---------------------------------------------------------------------
; メイン処理
;---------------------------------------------------------------------
MAIN
CALL DEVINIT
CALL LCDINIT
;
CALL VL6180INIT
CALL VL6180CONFIG
;
MOVLW D'255'
CALL DSPLCD
;
CLRF TOGGLE
MAIN_LP
;
CLRF RANGE
CALL READRANGE ; 測定
;
MOVF RANGE,W
SUBLW ACTDIST ; アクティブか否かチェック
BTFSS STATUS,C
GOTO INACT
; 前回もアクティブなら何もしない(そうしないと点滅する)
BTFSC TOGGLE,1
GOTO MAININTR
BSF TOGGLE,1 ; 前回アクティブではないのでトグル動作
GOTO TOGGLESW
;
INACT
BCF TOGGLE,1
GOTO MAININTR
TOGGLESW
MOVF TOGGLE,W
XORLW H'01'
MOVWF TOGGLE
;
BTFSS TOGGLE,0
GOTO $+3
BSF GPIO,LED
GOTO $+2
BCF GPIO,LED
;
MOVF RANGE,W
CALL DSPLCD ; LCD表示
;
CALL W05S ; トグル動作時は1秒待つ
CALL W05S
GOTO MAIN_LP
;
MAININTR
CALL W100MS ; 100ミリ秒ごとに測定
GOTO MAIN_LP
;
;---------------------------------------------------------------------
; 初期化
;---------------------------------------------------------------------
DEVINIT
CLRF INTCON ;全割込み禁止
;
BANKSEL CMCON
MOVLW B'00000111' ; GP0-2をデジタルI/Oに設定
MOVWF CMCON ; デフォルトはコンパレータ
; BANKSEL 1
; CALL 3FFH ; 内部OSCのキャリブレーションデータ
; MOVWF OSCCAL ; OSCCALレジスタにセット
BANKSEL TRISIO
MOVLW B'00000011' ; RA0,RA1 input
MOVWF TRISIO
BANKSEL GPIO
;
BCF GPIO,LED
;
RETURN
;
;---------------------------------------------------------------------
; 文字列表示
;---------------------------------------------------------------------
DSPTXT
MOVLW D'5'
MOVWF CNT
CLRF TMP
MOVLW BUFF
MOVWF FSR
;
MOVLW H'80' + H'0B' ; LCD1行目先頭へ
CALL LCDCMD
DSPTXTLP
MOVF CNT,W
DSPTXT1
MOVF INDF,W
CALL LCDDATA
INCF FSR,F
;
DECFSZ CNT,F
GOTO DSPTXTLP
;
RETURN
;---------------------------------------------------------------------
; LCD初期化(データシート通り)
;---------------------------------------------------------------------
LCDINIT
CALL W20MS ; 電源が安定するまでの待ち時間
CALL W20MS
;
MOVLW H'38' ; Function set
CALL LCDCMD
;
MOVLW H'39' ; Functino set
CALL LCDCMD
;
MOVLW H'14' ; Intrenal OSC frequency
CALL LCDCMD
;
; ; Contrast= B'10 1000' = D'40'
MOVLW H'70'+H'08' ; Contrast set
CALL LCDCMD
;
MOVLW H'54'+H'02' ; Power/ICON/Contrast control
; MOVLW H'51' ; +5V
CALL LCDCMD
;
MOVLW H'6C' ; Follower control
CALL LCDCMD
CALL W200MS
;
MOVLW H'38' ; Function set
CALL LCDCMD
;
MOVLW H'0C' + H'01' ; Display ON/OFF control
CALL LCDCMD
;
MOVLW H'01' ; Clear Display
CALL LCDCMD
;
RETURN
;
;---------------------------------------------------------------------
; LCDコマンド (W:CMD)
;---------------------------------------------------------------------
LCDCMD
MOVWF TMP ; 一時退避
;
MOVLW H'7C' ; I2Cアドレス
CALL I2CWSTART
MOVLW H'00' ; Command (RS=0)
MOVWF datao
CALL TX
MOVF TMP,W
MOVWF datao
CALL TX
CALL I2CSTOP
;
MOVLW H'01' ; Clear Display
SUBWF TMP,W
BTFSC STATUS,Z
GOTO LCDW1MS
MOVLW H'02' ; Return Home
SUBWF TMP,W
BTFSC STATUS,Z
GOTO LCDW1MS
;
CALL W27US ; Normal command
RETURN
LCDW1MS
CALL W1MS
RETURN
;
;---------------------------------------------------------------------
; LCD データ(Wレジ内容をLCDに書き込む)
;---------------------------------------------------------------------
LCDDATA
MOVWF TMP ; 書き込みデータ一時退避
;
MOVLW H'7C'
CALL I2CWSTART
;
MOVLW H'40' ; Data (RS=1)
MOVWF datao
CALL TX
;
MOVF TMP,W
MOVWF datao
CALL TX
;
CALL I2CSTOP
;
RETURN
;
;---------------------------------------------------------------------
; LCD表示(入力W)
;---------------------------------------------------------------------
DSPLCD
CLRF binH
MOVWF binL
CALL _bin2bcd ; BCD変換
;
MOVF bcdM,W
ANDLW H'0F'
ADDLW '0'
MOVWF BUFF
SWAPF bcdL,W
ANDLW H'0F'
ADDLW '0'
MOVWF BUFF+1
MOVF bcdL,W
ANDLW H'0F'
ADDLW '0'
MOVWF BUFF+2
;
MOVLW 'm'
MOVWF BUFF+3
MOVLW 'm'
MOVWF BUFF+4
;
; ゼロサプレス(上位桁が0なら空白にする)
MOVF BUFF,W
SUBLW '0'
BTFSS STATUS,Z
GOTO DISP
MOVLW ' '
MOVWF BUFF
MOVF BUFF+1,W
SUBLW '0'
BTFSS STATUS,Z
GOTO DISP
MOVLW ' '
MOVWF BUFF+1
DISP
CALL DSPTXT
RETURN
;
;---------------------------------------------------------------------
; VL6180レジスタindex (#define名は32文字まで)
;---------------------------------------------------------------------
#define READOUT__AVERAGING_SAMPLE_PERIOD 0x01,0x0A
#define SYSALS__ANALOGUE_GAIN 0x00,0x3F
#define SYSALS__INTEGRATION_PERIOD 0x00,0x40
#define SYSALS__INTERMEASUREMENT_PERIOD 0x00,0x3E
#define SYSRANGE__VHV_REPEAT_RATE 0x00,0x31
#define SYSRANGE__VHV_RECALIBRATE 0x00,0x2E
#define SYSRANGE__INTERMEASUREMENT_PERIO 0x00,0x1B
#define SYSRANGE__MAX_CONVERGENCE_TIME 0x00,0x1C
#define SYSTEM__INTERRUPT_CONFIG_GPIO 0x00,0x14
#define SYSTEM__INTERRUPT_CLEAR 0x00,0x15
#define INTERLEAVED_MODE__ENABLE 0x02,0xA3
#define RESULT__RANGE_STATUS 0x00,0x4D
#define RESULT__INTERRUPT_STATUS_GPIO 0x00,0x4F
#define SYSRANGE__START 0x00,0x18
#define RESULT__RANGE_VAL 0x00,0x62
;
;---------------------------------------------------------------------
; VL6180初期化(メモリ節約のためベタ書きではなくループを回した)
;---------------------------------------------------------------------
VL6180INIT
CALL W20MS
CLRF OFFSET
CALL REG8BITDT
MOVWF CNT1 ; 設定パラメタ数
VLINIT_LP1
MOVLW H'52' ; アドレス
CALL I2CWSTART
MOVLW D'3' ; indexHigh, indexLow, data の3バイトを送る
MOVWF CNT2
VLINIT_LP2
INCF OFFSET,F
CALL REG8BITDT
MOVWF datao
CALL TX ; I2C送信
DECFSZ CNT2,F
GOTO VLINIT_LP2
;
CALL I2CSTOP
;
DECFSZ CNT1,F
GOTO VLINIT_LP1
;
RETURN
REG8BITDT ; 以下のテーブルから順に取り出す
ORG H'200'
MOVLW H'02'
MOVWF PCLATH
MOVF OFFSET,W
ADDWF PCL,F
RETLW D'31' ; 31パラメタ
REG8BIT 0x02,0x07,0x01 ; indexHigh, indexLow, data
REG8BIT 0x02,0x08,0x01
REG8BIT 0x00,0x96,0x00
REG8BIT 0x00,0x97,0xFD ; RANGE_SCALER = 253
REG8BIT 0x00,0xE3,0x01
REG8BIT 0x00,0xE4,0x03
REG8BIT 0x00,0xE5,0x02
REG8BIT 0x00,0xE6,0x01
REG8BIT 0x00,0xE7,0x03
REG8BIT 0x00,0xF5,0x02
REG8BIT 0x00,0xD9,0x05
REG8BIT 0x00,0xDB,0xCE
REG8BIT 0x00,0xDC,0x03
REG8BIT 0x00,0xDD,0xF8
REG8BIT 0x00,0x9F,0x00
REG8BIT 0x00,0xA3,0x3C
REG8BIT 0x00,0xB7,0x00
REG8BIT 0x00,0xBB,0x3C
REG8BIT 0x00,0xB2,0x09
REG8BIT 0x00,0xCA,0x09
REG8BIT 0x01,0x98,0x01
REG8BIT 0x01,0xB0,0x17
REG8BIT 0x01,0xAD,0x00
REG8BIT 0x00,0xFF,0x05
REG8BIT 0x01,0x00,0x05
REG8BIT 0x01,0x99,0x05
REG8BIT 0x01,0xA6,0x1B
REG8BIT 0x01,0xAC,0x3E
REG8BIT 0x01,0xA7,0x1F
REG8BIT 0x00,0x30,0x00
REG8BIT 0x00,0x16,0x00 ;SYSTEM__FRESH_OUT_OF_RESET
;
;---------------------------------------------------------------------
; VL6180 configureDefault
;---------------------------------------------------------------------
VL6180CONFIG
CALL W20MS
CLRF OFFSET
CALL CONFIGDT
MOVWF CNT1 ; 設定パラメタ数
VLCONFIG_LP1
MOVLW H'52' ; アドレス
CALL I2CWSTART
MOVLW D'3' ; indexHigh, indexLow, data の3バイトを送る
MOVWF CNT2
VLCONFIG_LP2
INCF OFFSET,F
CALL CONFIGDT
MOVWF datao
CALL TX ; I2C送信
DECFSZ CNT2,F
GOTO VLCONFIG_LP2
;
CALL I2CSTOP
;
DECFSZ CNT1,F
GOTO VLCONFIG_LP1
;
; テーブルのラストにある16bitパラメタ1個のみ
MOVLW D'4' ; indexHigh, indexLow, dataHigh, dataLow の4バイトを送る
MOVWF CNT2
VLCONFIG_LP3
INCF OFFSET,F
CALL CONFIGDT
MOVWF datao
CALL TX ; I2C送信
DECFSZ CNT2,F
GOTO VLCONFIG_LP3
;
CALL I2CSTOP
;
RETURN
;
CONFIGDT ; 以下のテーブルから順に取り出す
MOVLW H'02'
MOVWF PCLATH
MOVF OFFSET,W
ADDWF PCL,F
RETLW D'9' ; 8bit 9パラメタ + 16bit 1パラメタ
REG8BIT READOUT__AVERAGING_SAMPLE_PERIOD,0x30
REG8BIT SYSALS__ANALOGUE_GAIN,0x46
REG8BIT SYSRANGE__VHV_REPEAT_RATE,0xFF
REG8BIT SYSRANGE__VHV_RECALIBRATE,0x01
REG8BIT SYSRANGE__INTERMEASUREMENT_PERIO,0x09 ; 100ms
REG8BIT SYSALS__INTERMEASUREMENT_PERIOD,0x31 ; 500ms
REG8BIT SYSTEM__INTERRUPT_CONFIG_GPIO,0x24
REG8BIT SYSRANGE__MAX_CONVERGENCE_TIME,0x31 ; 49ms
REG8BIT INTERLEAVED_MODE__ENABLE,0x00
REG16BIT SYSALS__INTEGRATION_PERIOD,0x00,0x63 ; 16bitパラメタ(1個のみ)
;
;---------------------------------------------------------------------
; VL6180 readRange
;---------------------------------------------------------------------
READRANGE
; デバイスがreadyになるまで待つ
RDREG RESULT__RANGE_STATUS
MOVF datai,W
ANDLW H'01'
BTFSC STATUS,Z
GOTO READRANGE
;
; 測定開始フラグ設定
WTREG SYSRANGE__START,0x01
;
CLRF TIMOUTH ; タイムアウトカウント用
CLRF TIMOUTL
READRANGLP
CALL CHKTIMEOUT ; タイムアウト確認
BTFSS STATUS,Z
GOTO READRANGE2
MOVLW D'255' ; タイムアウト
MOVWF RANGE
RETURN
;
READRANGE2
; 測定完了確認
RDREG RESULT__INTERRUPT_STATUS_GPIO
MOVF datai,W
ANDLW 0x07
SUBLW 0x04
BTFSS STATUS,Z
GOTO READRANGLP
;
; 値を読み出す
RDREG RESULT__RANGE_VAL
MOVF datai,W
MOVWF RANGE
;
; 割り込みフラグクリア
WTREG SYSTEM__INTERRUPT_CLEAR, 0x01
;
RETURN
;
;---------------------------------------------------------------------
; センサのタイムアウトチェック(500ms)
; 1回の測定にざっと200usかかるとして 500ms/200us ... TIMOUTH=10
;---------------------------------------------------------------------
CHKTIMEOUT
MOVF TIMOUTL,W
ADDLW D'1'
MOVWF TIMOUTL
BTFSS STATUS,Z
RETURN
;
MOVF TIMOUTH,W
ADDLW D'1'
MOVWF TIMOUTH
SUBLW D'10' ; Zフラグを持ってリターン
RETURN
;---------------------------------------------------------------------
; ウェイト色々
;---------------------------------------------------------------------
W27US
MOVLW D'7'
MOVWF WAIT1
W27USLP
DECFSZ WAIT1,F
GOTO W27USLP
NOP
RETURN
;
W1MS
MOVLW D'110'
MOVWF WAIT1
W1MSLP
GOTO $+1
GOTO $+1
GOTO $+1
DECFSZ WAIT1,F
GOTO W1MSLP
GOTO $+1
GOTO $+1
NOP
RETURN
;
W20MS
MOVLW D'20'
MOVWF WAIT2
W20MSLP
CALL W1MS
DECFSZ WAIT2,F
GOTO W20MSLP
RETURN
;
W100MS
MOVLW D'100'
MOVWF WAIT2
W100MSLP
CALL W1MS
DECFSZ WAIT2,F
GOTO W100MSLP
RETURN
;
W200MS
MOVLW D'200'
MOVWF WAIT2
W200MSLP
CALL W1MS
DECFSZ WAIT2,F
GOTO W200MSLP
RETURN
;
W05S
MOVLW D'100'
MOVWF WAIT2
W05SLP
CALL W1MS
CALL W1MS
CALL W1MS
CALL W1MS
CALL W1MS
DECFSZ WAIT2,F
GOTO W05SLP
RETURN
;
;---------------------------------------------------------------------
; I2Cアクセスルーチン
; 流用元:Microchip Applicatin Note : AN982
; Interfacing I2C Serial EEPROMs to PIC10 and PIC12 Drivers
;---------------------------------------------------------------------
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
; Filename: i2c_routines.inc
; Date: March 21, 2005
; File Version: 1.0
; Assembled using: MPLAB IDE 7.00.00.0
;
; Author: Chris Parris
; Company: Microchip Technology, Inc.
;
;*******************RAM register definitions**********************
#define STARTRAM 0x40 ; Start RAM at address 0x40
cblock STARTRAM
buffer ; Transfer/Receive bit buffer
datai ; Data input byte buffer
datao ; Data output byte buffer
bitcount ; Bit loop counter
bytecount ; Byte loop counter
addressH ; Word address pointer
addressL ; Word address pointer
loops ; Delay loop counter
loops2 ; Delay loop counter
pollcnt ; Polling loop counter
i2caddr
endc
;*******************Bit definitions*******************************
DO equ 0 ; TX/RX buffer output bit
DI equ 1 ; TX/RX buffer input bit
ACKB equ 2 ; ACK/NO ACK select bit
;*******************Delay Macros**********************************
; Each macro delay for 1 inst. cycle less than
; required, as the instruction immediately
; before the macro call provides 1 inst. cycle.
;*****************************************************************
THIGH macro ; Clock high time delay (5 us)
goto $+1 ; 2-inst. cycle delay (2 us)
goto $+1 ; 2-inst. cycle delay (2 us)
nop ; 1us
endm
THDSTA macro ; Start condition hold time delay (5 us)
goto $+1 ; 2-inst. cycle delay (2 us)
goto $+1 ; 2-inst. cycle delay (2 us)
nop ; 1us
endm
TSUSTA macro ; Start condition setup time delay (5 us)
goto $+1 ; 2-inst. cycle delay (2 us)
goto $+1 ; 2-inst. cycle delay (2 us)
nop ; 1us
endm
TSUSTO macro ; Stop condition setup time delay (5 us)
goto $+1 ; 2-inst. cycle delay (2 us)
goto $+1 ; 2-inst. cycle delay (2 us)
nop ; 1us
endm
TAA macro ; Output valid from clock delay (4 us)
goto $+1 ; 2-inst. cycle delay (2 us)
goto $+1 ; 2-inst. cycle delay (2 us)
endm
;-------------------------------------------------------------------
; I2Cアクセス
;-------------------------------------------------------------------
I2CWSTART
MOVWF i2caddr ; I2Cアドレス退避
call BSTART ; Generate start bit
; Now send the control byte
; for a write, to set address
movf i2caddr,W ; I2Cアドレス
movwf datao ; Copy control byte to buffer
call TX ; Output control byte to device
RETURN
I2CSTOP
CALL NOACK
call BSTOP ; Generate stop bit
RETURN
;
I2CRSTART
IORLW H'01'
MOVWF i2caddr ; I2Cアドレス退避
call BSTART ; Generate start bit
; Now send the control byte
; for a write, to set address
movf i2caddr,W
movwf datao ; Copy control byte to buffer
call TX ; Output control byte to device
RETURN
;*******************Start bit subroutine**************************
; This routine generates a Start condition
; (high-to-low transition of SDA while SCL
; is still high.
;*****************************************************************
BSTART
bsf GPIO,SCL ; Make sure SCL is high
TSUSTA ; Start condition setup time delay
BANKSEL 1
BCF TRISIO,SDA ; Configure SDA to be an output
BANKSEL 0
bcf GPIO,SDA ; Pull SDA low to initiate
; Start condition
THDSTA ; Start condition hold time delay
bcf GPIO,SCL ; Bring SCL low in preparation
; for data transfer
BANKSEL 1
BSF TRISIO,SDA ; Configure SDA to be an input
BANKSEL 0
retlw 0
;*******************Stop bit subroutine***************************
; This routine generates a Stop condition
; (low-to-high transition of SDA while SCL
; is still high.
;*****************************************************************
BSTOP
BANKSEL 1
BCF TRISIO,SDA ; Configure SDA to be an output
BANKSEL 0
bcf GPIO,SDA ; Pull SDA low
bsf GPIO,SCL ; Make sure SCL is high
TSUSTO ; Stop condition setup time delay
BANKSEL 1
BSF TRISIO,SDA ; Configure SDA to be an input
BANKSEL 0
retlw 0
;*******************Bit output subroutine*************************
; This routine outputs bit 'DO' in 'buffer' to
; the serial EEPROM device.
;*****************************************************************
BITOUT
bcf GPIO,SCL ; Make sure SCL is low
btfss buffer,DO ; Check for state of bit to xmit
goto bitlow ; If bit is low, pull SDA low
clockout ; If bit is high, leave SDA high
bsf GPIO,SCL ; Bring SCL high to begin transfer
THIGH ; Clock high time delay
bcf GPIO,SCL ; Bring SCL low again
BANKSEL 1
BSF TRISIO,SDA ; Configure SDA to be an input
BANKSEL 0
retlw 0
bitlow
BANKSEL 1
BCF TRISIO,SDA ; Configure SDA to be an output
BANKSEL 0
bcf GPIO,SDA ; Pull SDA low
goto clockout
;*******************Bit input subroutine**************************
; This routine inputs a bit of data from the
; serial EEPROM device, and stores it in bit
; 'DO' of 'buffer'.
;*****************************************************************
BITIN
bcf GPIO,SCL ; Make sure SCL is low
BANKSEL 1
BSF TRISIO,SDA ; Configure SDA to be an input
BANKSEL 0
bsf buffer,DI ; Assume input bit is high
bsf GPIO,SCL ; Bring SCL high to begin transfer
TAA ; Output valid from clock delay
btfss GPIO,SDA ; Check for state of SDA bit
bcf buffer,DI ; If SDA is low, set bit low
bcf GPIO,SCL ; Bring SCL low again
retlw 0
;*******************Data transmit subroutine**********************
; This routine transmits the byte of data
; stored in 'datao' to the serial EEPROM
; device. Instructions are also in place
; to check for an ACK bit, if desired.
; Just replace the 'goto' instruction,
; or create an 'ackfailed' label, to provide
; the functionality.
;*****************************************************************
TX
movlw .8
movwf bitcount ; Initialize loop counter to 8
txlp
bsf buffer,DO ; Assume output bit is high
btfss datao,7 ; Check state of next output bit
bcf buffer,DO ; If low, set buffer bit low
call BITOUT ; Call routine to output bit
rlf datao,F ; Rotate datao left for next bit
decfsz bitcount,F ; Decrement counter, check if done
goto txlp ; Keep looping
CALL ACK
retlw 0
;*******************Data receive subroutine***********************
; This routine reads in one byte of data from
; the serial EEPROM device, and stores it in
; 'datai'. It then responds with either an
; ACK or a NO ACK bit, depending on the value
; of 'ACKB' in 'buffer'.
;*****************************************************************
RX
clrf datai ; Clear input buffer
movlw .8
movwf bitcount ; Initialize loop counter to 8
bcf STATUS,C ; make sure carry bit is low
rxlp
rlf datai,F ; Rotate datai 1 bit left
call BITIN ; Read a bit
btfsc buffer,DI
bsf datai,0 ; Set bit 0 if necessary
decfsz bitcount,F ; 8 bits done?
goto rxlp ; If not, do another
call BITIN ; Call routine to read ACK bit
RETLW 0
ACK
bcf buffer,DO ; If ACKB = 1, send ACK (DO = 0)
call BITOUT ; Send bit
retlw 0
NOACK
bsf buffer,DO ; If ACKB = 1, send ACK (DO = 0)
call BITOUT ; Send bit
retlw 0
;
;---------------------------------------------------------------------
;---------------------------------------------------------------------
; 16-bit binary to BCD conversion
; pete griffiths 2007
; http://picprojects.org.uk/projects/pictips.htm
;
; These file register variables will
; need to be defined elsewhere.
; binH
; binL
; bcdH
; bcdM
; bcdL
; counter
; temp
;
; binH, binL contain the binary value to
; convert. Conversion process destroys contents.
; Result is in bcdH, bcdM, bcdL on return.
; Call _bin2bcd to perform conversion.
;
; Executes in 454 instructions
_bin2bcd movlw d'16'
movwf counter
clrf bcdL
clrf bcdM
clrf bcdH
_repeat rlf binL,F
rlf binH,F
rlf bcdL,F
rlf bcdM,F
rlf bcdH,F
decfsz counter,F
goto _adjust
return
_adjust movlw d'14'
subwf counter,W
skpnc
goto _repeat
movfw bcdL
addlw 0x33
movwf temp
movfw bcdL
btfsc temp,3
addlw 0x03
btfsc temp,7
addlw 0x30
movwf bcdL
movfw bcdM
addlw 0x33
movwf temp
movfw bcdM
btfsc temp,3
addlw 0x03
btfsc temp,7
addlw 0x30
movwf bcdM
goto _repeat
; we only need to do the test and add +3 for
; the low and middle bcd variables since the
; largest binary value is 0xFFFF which is
; 65535 decimal so the high bcd byte variable
; will never be greater than 6.
; We also skip the tests for the first two
; shifts.
;---------------------------------------------------------------------
END
;---------------------------------------------------------------------
; 終わり
;---------------------------------------------------------------------
2026年2月20日金曜日
TOFセンサをPIC12F629で使う(動いた)
ようやくTOFセンサ VL6180X をPIC12F629で動かすことができました。設定パラメタを何度も見返したりしましたが分かりません。他のArduinoライブラリを見たりしても大きな違いはないように見えました。
基本に戻ってI2Cのコードを見ていたら読み出しのタイミングにおかしいところがあるのに気付きました。そこを直したら難なく動いた次第。トホホです。取り合えず書いたコードなので、この3連休で少しキレイにしようかと思います。
2026年2月15日日曜日
TOFセンサをPIC12F629で使う(使えてない)
昨日書いたChatGPTから吐き出されたコードがダメダメだった 件の続きで、コードを自力で書いてみました。先に結論を言うとまだ使えてません。VL6180Xはムズイ。
使ったのはPIC12F629という古い8ピンタイプで、メモリ1Kワード、I2Cなしです。うまく動いたArduinoのTOPセンサVL6180Xライブラリコードを見ながらアセンブラで移植しました。古いアーキのPICなので最近の便利な命令が使えません。それでも書き始めたら思い出してきてなんとかなった(なってない)。
Arduinoのライブラリを丸ごと移植するのは大変だし、メモリ容量的にも厳しい。適当に端折って移植しましたが、上手く動きません。初期化、コンフィグ、距離測定の3機能だけですが、ダメです。距離が7mmで返ってきます。最小値かな? I2C接続のLCDには表示できているのでI2Cは大丈夫だと思う。端折ってしまったところで、何か必要な設定ができていないのか、処理の呼び出し方をミスっているのかと推測。
朝からコードを見直して1か所、設定場所を間違えている箇所に気付いて修正しましたが、結果は変わらず。根を詰めてもよろしくないし、頭を切り替えたら何か思いつくかもという期待を込めて今日はここまで。
2026年2月14日土曜日
PICプログラムをchatGPTに書いてもらったけど、、、
先日試したTOF測距センサ をPICマイコンで使いたくて、chatGPTにプログラムを書いてもらったりしていた。しかし、全然動かない。
依頼したプロンプトは以下のような感じ。
PIC12F629マイコンとTOFセンサVL6180を使って近接センサによるスイッチを作りたい。 回路(ピンの接続)とプログラムが欲しい ・あらかじめ設定した距離(cm単位で10~20cm)に近づくとオンオフ動作する ・距離の設定はプログラム内の#defineで行う ・オンオフはオルタネイト。一度近づくとオン、離れたのちもう一度近づくとオフ ・オンの間はLEDが点灯する。最終的にはこれをSSRのLEDにする。 ・誤動作防止のためオンオフは指定された距離で200ms程度継続したら認識する ・オンオフの間はチャタリング防止のため500m秒程度あける(これより短い時間でオンオフしない) ・PIC12F629はI2Cモジュールがないので、ソフトウェアでI2Cを行う
・プログラムはアセンブラで書く ・適度に関数に分けたコードが欲しい(後で人手で直せるように処理内容のコメントも記載) ・プログラム書き込みに使用するピン(GP1:ICSPCLK,GP2:ISCPDAT)は使わない ・MPLABでそのままビルドできる1ファイル化 ・クロックは内蔵発信4MHz
吐き出してきたソースを見るとI2C通信のタイミングを全く無視しているし、ACKも見てない。それを指摘すると、それっぽいソースになったがまだダメです。また、TOFセンサの初期化も適当でこれで初期化できるの?という感じ。Arduinoのライブラリのソースを見ると結構多くのパラメタを設定していた。
簡単にできると思っていたのが甘かった。しかたないので諦めて自分で書くことにしました。有料のClaude codeなどを使えばすぐ動くコードを出してくれるのかな?
今日の日経に以下の記事が掲載されていた(クリックで拡大)。先日来のアンソロピックショックでITサービス系の株価が下落しているのにさらに追い打ちかけてきます。NASDAQ, FANG+が下がって痛手。
AIが自分自身を書き換えて進化し続けたらちょっと怖いな。イーロンマスクが軌道上にAIデータセンタを作るらしいし、そこでAIが自律的に動き出したら簡単に止められない。というようなディストピアSF、映画ターミネータのスカイネットを想像してしまう。
2026年2月7日土曜日
東京アプリでポイントをゲットしたけど
先日、東京アプリによる給付について書きました が一応、ポイント申請してみました。今朝メールが届いたのでアプリで確認したら保有ポイントが11,000Pになっていた。申請してからポイントが付くまで1日半ほどでした。
で、d払いアプリなるものを入れて使うらしいとのことで、入れてポイントをみたら12,345円になっていた。限定123Pというのが分からないけど。それでも1,000ポイントより多い。この12345というのはサンプル画面なのか?
よく分からないけどあまり信用できそうにないのと色々操作を覚えないと使いこなせそうにないので、早めにポイントを使い切って東京アプリもdポイントアプリもアンインストールしようと思う。とにかくアプリやらポイントに振り回されず、生活をシンプルにしたい。
ドコモに渡した個人情報のみ少し後悔。こんなことなら11,000P諦めればよかった。
(追記26.2.7) 東京アプリと認証アプリはアンインストールしたけどアカウントは残ったままになるのかな?アプリを消す前にアカウント削除すべきだったか?
(追記26.2.14) 東京アプリのアカウントの削除は、アプリ内でしかできないようだったので、アプリを入れ直して、アカウント削除(退会)しました。その後再度アンインストール。アマゾンとの連携も個人情報がどこまで連携されるのか不安でやめることにした。で、dポイントはリアル店で使い始めましたが最初手間取りました。早いとこ使い切りたい。最後に残るだろう千円以下の端数ポイントは、普段dポイントを使っている知人にあげちゃうつもり。
2026年2月4日水曜日
東京アプリ生活応援事業について
東京都が実施する生活支援キャンペーンで、東京都が公式スマートフォンアプリ「東京アプリ」を通じて、現金ではなく 11,000ポイント(1ポイント = 1円相当)受け取れる給付制度です。2月2日からはじまった。
よくわからなかったのでchatGPTとチャットして色々と教えてもらったら、驚愕の事実が、、、(検証はしてないので間違いがあるかも)
まず、付与されたポイントは以下の民間のポイントサービスに1ポイント=1円で交換できるらしい。
- dポイント
- au PAY残高
- 楽天ペイ(楽天ポイント)
- Vポイント(V Point)
- メルカリポイント
しかし個人的にはこれらのポイントサービスは使ってない。昔からポイントカードとかは面倒で使ってないのです。例外はポイントサービスの元祖であるヨドバシのポイント、アマゾンのポイント、クレジットカードのポイントだけ。
chatGPTが言うにはdポイントはアマゾンと連携して使えるらしい。でもアマゾンギフトカードは買えないよ、と教えてくれた。手順は以下のような感じ。
- iPhoneに東京アプリを入れる、マイナンバーカードの認証アプリも必要らしい
- アプリ上でマイナンバーカードを使ってポイントの申請をする
- dポイントのアプリを入れてdポイントのアカウントを作る。(ドコモユーザでなくても無料で作れるらしい)
- ポイントが支給されたら東京アプリ上でdポイントに交換する
- アマゾンでdポイント連携を設定する
- アマゾンで買い物するときに普段のカードではなく、dポイント連携払いにする
以上、面倒な作業が続く。「スマホが使えない独居の高齢者に無理だね」ということをchatGPTに聞いたら、「そうですね、本当に困窮している人には届かない施策」とのこと。
事業費なども聞いたら、給付用に450億円で、これは支給対象者の約1/3分しかない。要するに、元々全員に配る(申請する)とは考えてない。また、給付額を含む総事業費が799億円とのことなので349億円がシステム構築、運用管理、宣伝費など。これらには職員の人件費は含まないようなので、それを含めたらもっとかかっている計算。
- お金かけてなんでこんな面倒な仕組みなの?
- 現金給付じゃダメなの?(マイナンバーに給付金口座を紐づけたよね)
- 配るならそもそも税金を下げてよ
なんだかなぁ、と思った次第。個人的には残された時間を考えると極力手間のかかることに時間を使いたくない、と思う今日この頃。でもサーバの混雑が解消したころに申請すると思う。












































