avr/reed: implemented tilt detection mode
- implemented tilt detection mode - added docu - change the way a VALUE2 message is printed when value type is "door"
This commit is contained in:
@@ -8,6 +8,41 @@
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
; This module monitors up to two reed contacts to determine whether a windows
|
||||
; door is open.
|
||||
;
|
||||
; It has two modes.
|
||||
;
|
||||
; Standard Mode
|
||||
; -------------
|
||||
;
|
||||
; In this mode up to two windows can be monitored. Each reed contact is reported on separately.
|
||||
; If a window/door is open a value of 255 is reported, 0 otherwise.
|
||||
|
||||
; Tilt Detect Mode
|
||||
; ----------------
|
||||
;
|
||||
; In this mode both reed sensors are handled together to determine whether a window
|
||||
; or door is closed, tilted or fully open.
|
||||
; - if exactly one of two reed contacts is open the window/door is reported as tilted (value 128)
|
||||
; - if both reed contacts are open the window/door is reported as fully open (value 255)
|
||||
; - if both reed contacts are closed the window/door is reported as closed (value 0)
|
||||
;
|
||||
;
|
||||
; The window state is reported via the VALUE message with a value id of VALUE_ID_REED1 for the
|
||||
; first reed contact (or for the whole window/door if in tilt detection mode), for the second
|
||||
; reed contact a value id of VALUE_ID_REED2 is used. Value type is always AQHOME_VALUETYPE_DOOR
|
||||
; (i.e. for doors and windows).
|
||||
;
|
||||
; There are basically two types of reed contacts.
|
||||
; - normally closed (NC): The contact is closed as long as the magnet is near the switch.
|
||||
; If the magnet is removed the contact opens.
|
||||
; This is the default working mode of this module.
|
||||
; - normally open (NO): The contact is open as long as the magnet is near the switch.
|
||||
; If the magnet is removed the contact closes.
|
||||
; To account for those different types of working modes this mode is configurable.
|
||||
|
||||
|
||||
|
||||
; The state byte contains the state for two reed contacts (one in each nibble).
|
||||
;
|
||||
@@ -28,16 +63,25 @@
|
||||
.equ REED_STATE_MASK_BEFORELAST = 0x2
|
||||
.equ REED_STATE_MASK_LAST = 0x1
|
||||
|
||||
.equ REED_STATE_MASK_LASTVALUES = 0x3 ; bits 0 and 1
|
||||
.equ REED_STATE_BIT_CURRENT = 3
|
||||
.equ REED_STATE_BIT_CHANGED = 2
|
||||
.equ REED_STATE_MASK_LASTVALUES = 0x3 ; bits 0 and 1
|
||||
.equ REED_STATE_BIT_CURRENT = 3
|
||||
.equ REED_STATE_BIT_CHANGED = 2
|
||||
|
||||
|
||||
.equ REED_CONFIG_MASK_SET = 0x80
|
||||
.equ REED_CONFIG_MASK_MULTI = 0x40
|
||||
.equ REED_CONFIG_MASK_NO = 0x20 ; if set: normally open (e.g. disconnected when magnet near)
|
||||
.equ REED_CONFIG_MASK_SET = 0x80
|
||||
.equ REED_CONFIG_MASK_TILTDETECT = 0x40 ; use both reed contacts to detect tilted windows
|
||||
.equ REED_CONFIG_MASK_NO = 0x20 ; if set: normally open (e.g. disconnected when magnet near)
|
||||
|
||||
.equ REED_CONFIG_BIT_TILTDETECT = 6
|
||||
.equ REED_CONFIG_BIT_NO = 5
|
||||
|
||||
|
||||
.equ REED_INITIAL_CONFIG = REED_CONFIG_MASK_SET
|
||||
|
||||
|
||||
.equ REED_CFGMOD_CMD_SETCONFIG = 1 ; only command for now
|
||||
|
||||
|
||||
.equ REED_INITIAL_CONFIG = REED_CONFIG_MASK_SET
|
||||
|
||||
|
||||
|
||||
@@ -54,6 +98,9 @@ reedDataEnd:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; code
|
||||
|
||||
@@ -99,6 +146,7 @@ REED_Fini:
|
||||
|
||||
|
||||
REED_Run:
|
||||
clc ; debug
|
||||
ret ; debug
|
||||
push r15
|
||||
in r15, SREG
|
||||
@@ -106,6 +154,7 @@ REED_Run:
|
||||
rcall reedHandleChanges
|
||||
out SREG, r15
|
||||
pop r15
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
@@ -150,7 +199,8 @@ reedSetupConfig:
|
||||
brne reedSetupConfig_haveConfig
|
||||
reedSetupConfig_noConfig:
|
||||
ldi r16, REED_INITIAL_CONFIG
|
||||
rcall Utils_WriteEepromIncr
|
||||
; disabled for now
|
||||
; debug rcall Utils_WriteEepromIncr
|
||||
reedSetupConfig_haveConfig:
|
||||
sts reedConfigFromEeprom, r16
|
||||
reedSetupConfig_end:
|
||||
@@ -164,6 +214,20 @@ reedSetupConfig_end:
|
||||
; @clobbers all
|
||||
|
||||
reedHandleChanges:
|
||||
lds r16, reedConfigFromEeprom
|
||||
sbrc r16, REED_CONFIG_BIT_TILTDETECT
|
||||
rjmp reedHandleChangesTiltDetectMode
|
||||
rjmp reedHandleChangesSingleMode
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine reedHandleChangesSingleMode
|
||||
;
|
||||
; @clobbers all
|
||||
|
||||
reedHandleChangesSingleMode:
|
||||
lds r19, reedState
|
||||
|
||||
; reed 1
|
||||
@@ -194,6 +258,54 @@ reedHandleChanges:
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine reedHandleChangesTiltDetectMode
|
||||
;
|
||||
; Handle changes in multi reed contact mode.
|
||||
; This allows for detection of tilted windows/doors.
|
||||
;
|
||||
; @clobbers all
|
||||
|
||||
reedHandleChangesTiltDetectMode:
|
||||
lds r19, reedState
|
||||
|
||||
mov r16, r19
|
||||
andi r16, (REED_STATE_MASK_CHANGED | (REED_STATE_MASK_CHANGED<<4))
|
||||
breq reedHandleChangesTiltDetectMode_end ; no changes
|
||||
; at least one contact changed, handle new state
|
||||
clr r16
|
||||
sbrc r19, REED_STATE_BIT_CURRENT
|
||||
inc r16
|
||||
sbrc r19, (REED_STATE_BIT_CURRENT+4)
|
||||
inc r16
|
||||
; no check for full state (0=closed, 1=tilted, 2=fully open)
|
||||
tst r16
|
||||
breq reedHandleChangesTiltDetectMode_closed
|
||||
cpi r16, 1
|
||||
breq reedHandleChangesTiltDetectMode_tilted
|
||||
; otherwise fully open, fallthrough
|
||||
ldi r16, 255
|
||||
rjmp reedHandleChangesTiltDetectMode_sendChanges
|
||||
reedHandleChangesTiltDetectMode_closed:
|
||||
ldi r16, 0
|
||||
rjmp reedHandleChangesTiltDetectMode_sendChanges
|
||||
reedHandleChangesTiltDetectMode_tilted:
|
||||
ldi r16, 128
|
||||
reedHandleChangesTiltDetectMode_sendChanges:
|
||||
ldi r17, VALUE_ID_REED1
|
||||
push r19
|
||||
rcall reedSendChange
|
||||
pop r19
|
||||
brcc reedHandleChangesTiltDetectMode_end
|
||||
; changes handled, clear change flags and write back
|
||||
andi r19, ~(REED_STATE_MASK_CHANGED | (REED_STATE_MASK_CHANGED<<4))
|
||||
sts reedState, r19
|
||||
reedHandleChangesTiltDetectMode_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine reedSendValueIfChanged
|
||||
;
|
||||
@@ -250,26 +362,34 @@ reedSendChange:
|
||||
;
|
||||
; Updates SDRAM variable reedState according to current pin states.
|
||||
;
|
||||
; @clobbers r16, r17, r18, r19
|
||||
; @clobbers r16, r17, r18, r19, r20
|
||||
|
||||
reedUpdateState:
|
||||
lds r19, reedState ; current reed state
|
||||
lds r20, reedConfigFromEeprom
|
||||
|
||||
; handle reed 1 (low nibble state)
|
||||
rcall reedReadValue1 ; (r16)
|
||||
rcall reedReadValue1 ; (r16)
|
||||
sbrc r20, REED_CONFIG_BIT_NO
|
||||
com r16 ; invert reed data if "normally open" contact
|
||||
andi r16, 1
|
||||
mov r17, r16
|
||||
mov r16, r19
|
||||
rcall reedUpdateStateNibble ; (r18)
|
||||
rcall reedUpdateStateNibble ; (r18)
|
||||
; replace lower state nibble with new value
|
||||
andi r16, 0x0f ; only keep low nibble
|
||||
andi r19, 0xf0 ; clear out low nibble before or'ing new value in
|
||||
andi r16, 0x0f ; only keep low nibble
|
||||
andi r19, 0xf0 ; clear out low nibble before or'ing new value in
|
||||
or r19, r16
|
||||
|
||||
; handle reed2 (high nibble state)
|
||||
rcall reedReadValue2 ; (r16)
|
||||
rcall reedReadValue2 ; (r16)
|
||||
sbrc r20, REED_CONFIG_BIT_NO
|
||||
com r16 ; invert reed data if "normally open" contact
|
||||
andi r16, 1
|
||||
mov r17, r16
|
||||
mov r16, r19
|
||||
swap r16
|
||||
rcall reedUpdateStateNibble ; (r18)
|
||||
rcall reedUpdateStateNibble ; (r18)
|
||||
swap r16
|
||||
; replace higher state nibble with new value
|
||||
andi r16, 0xf0
|
||||
|
||||
Reference in New Issue
Block a user