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:
Martin Preuss
2023-05-12 23:19:01 +02:00
parent 84403d07f6
commit 226922d3e4
5 changed files with 227 additions and 46 deletions

View File

@@ -29,6 +29,7 @@
uint32_t AQH_Value2Msg_GetUid(const GWEN_MSG *msg)
{
return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_VALUE2_UID, 0);
@@ -72,6 +73,20 @@ const char *AQH_Value2Msg_GetValueTypeName(const GWEN_MSG *msg)
switch(t) {
case AQH_MSG_VALUE2_TYPE_TEMP: return "temperature";
case AQH_MSG_VALUE2_TYPE_HUMIDITY: return "humidity";
case AQH_MSG_VALUE2_TYPE_DOOR: return "door/window";
default: break;
}
return "unknown";
}
const char *AQH_Value2Msg_GetValueAsWindowStateString(const GWEN_MSG *msg)
{
switch(AQH_Value2Msg_GetValueNom(msg)) {
case 0: return "closed";
case 128: return "tilted";
case 255: return "fully open";
default: break;
}
return "unknown";
@@ -106,6 +121,16 @@ void AQH_Value2Msg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const ch
{
if ((AQH_NodeMsg_GetMsgType(msg)==AQH_MSG_TYPE_VALUE2) &&
(GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_VALUE2_MINSIZE)) {
if (AQH_Value2Msg_GetValueType(msg)==AQH_MSG_VALUE2_TYPE_DOOR)
GWEN_Buffer_AppendArgs(dbuf, "0x%02x->0x%02x: VALUE2 %s (uid=0x%08x, value_id=0x%02x type=%s value=%s)\n",
AQH_NodeMsg_GetSourceAddress(msg),
AQH_NodeMsg_GetDestAddress(msg),
sText,
(unsigned int) AQH_Value2Msg_GetUid(msg),
AQH_Value2Msg_GetValueId(msg),
AQH_Value2Msg_GetValueTypeName(msg),
AQH_Value2Msg_GetValueAsWindowStateString(msg));
else
GWEN_Buffer_AppendArgs(dbuf, "0x%02x->0x%02x: VALUE2 %s (uid=0x%08x, value_id=0x%02x type=%s value=%f)\n",
AQH_NodeMsg_GetSourceAddress(msg),
AQH_NodeMsg_GetDestAddress(msg),
@@ -120,4 +145,3 @@ void AQH_Value2Msg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const ch

View File

@@ -20,6 +20,7 @@
#define AQH_MSG_VALUE2_TYPE_TEMP 1
#define AQH_MSG_VALUE2_TYPE_HUMIDITY 2
#define AQH_MSG_VALUE2_TYPE_DOOR 3
@@ -31,6 +32,7 @@ AQHOME_API int16_t AQH_Value2Msg_GetValueDenom(const GWEN_MSG *msg);
AQHOME_API double AQH_Value2Msg_GetValue(const GWEN_MSG *msg);
AQHOME_API const char *AQH_Value2Msg_GetValueAsWindowStateString(const GWEN_MSG *msg);
AQHOME_API void AQH_Value2Msg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText);

View File

@@ -302,6 +302,33 @@ Offset Length Meaning
Config Module Request Message
=============================
Offset Length Meaning
---------------------------------------------------------
0 1 destination address
1 1 remaining message length
2 1 command code
3 1 source address
---------------------------------------------------------
4 1 module id
5 1 module command
6 n command data (depending on module and command)
Config Module Response Message
==============================
Offset Length Meaning
---------------------------------------------------------
0 1 destination address
1 1 remaining message length
2 1 command code
3 1 source address
---------------------------------------------------------
4 1 response code

View File

@@ -42,12 +42,20 @@
.equ CPRO_CMD_REBOOT_REQUEST = 90
.equ CPRO_CMD_REBOOT_RESPONSE = 91
.equ CPRO_CMD_CONFIG_MODULE_REQUEST = 100
.equ CPRO_CMD_CONFIG_MODULE_RESPONSE = 101
.equ CPRO_PACKET_HAVEADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4
.equ CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4
.equ CPRO_PACKET_DENYADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4
.equ CPRO_PACKET_REBOOTREQ_OFFS_UID = COM2_MSG_OFFS_PAYLOAD+0
.equ CPRO_PACKET_CFGMOD_REQUEST_OFFS_MODID = COM2_MSG_OFFS_PAYLOAD+0
.equ CPRO_PACKET_CFGMOD_REQUEST_OFFS_MODCMD = COM2_MSG_OFFS_PAYLOAD+1
.equ CPRO_PACKET_CFGMOD_REQUEST_OFFS_DATA = COM2_MSG_OFFS_PAYLOAD+2
.equ CPRO_WAITTIME_INITIAL = 10
.equ CPRO_WAITTIME_GETADDR = 130
.equ CPRO_WAITTIME_CLAIMADDR = 17

View File

@@ -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).
;
@@ -34,12 +69,21 @@
.equ REED_CONFIG_MASK_SET = 0x80
.equ REED_CONFIG_MASK_MULTI = 0x40
.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
; ***************************************************************************
@@ -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,12 +362,17 @@ 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)
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)
@@ -266,6 +383,9 @@ reedUpdateState:
; handle reed2 (high nibble state)
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