diff --git a/avr/modules/f_keepup/0BUILD b/avr/modules/f_keepup/0BUILD
new file mode 100644
index 0000000..febd367
--- /dev/null
+++ b/avr/modules/f_keepup/0BUILD
@@ -0,0 +1,11 @@
+
+
+
+
+
+ main.asm
+
+
+
+
+
diff --git a/avr/modules/f_keepup/main.asm b/avr/modules/f_keepup/main.asm
new file mode 100644
index 0000000..7f24efd
--- /dev/null
+++ b/avr/modules/f_keepup/main.asm
@@ -0,0 +1,107 @@
+; ***************************************************************************
+; copyright : (C) 2025 by Martin Preuss
+; email : martin@libchipcard.de
+;
+; ***************************************************************************
+; * This file is part of the project "AqHome". *
+; * Please see toplevel file COPYING of that project for license details. *
+; ***************************************************************************
+
+
+; ***************************************************************************
+; defines
+
+.equ FILTER_KEEPUP_OFFS_TIMER = 0
+.equ FILTER_KEEPUP_OFFS_RESTARTVALUE = 1
+.equ FILTER_KEEPUP_DATA_SIZE = 2
+
+
+
+; ***************************************************************************
+; code
+
+.cseg
+
+
+
+; ---------------------------------------------------------------------------
+; @routine FilterKeepUp_Init @global
+;
+; @param Y pointer to filter data
+; @clobbers r16
+
+FilterKeepUp_Init:
+ clr r16
+ std Y+FILTER_KEEPUP_OFFS_TIMER, r16
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine FilterKeepUp_Fini @global
+;
+; @param Y pointer to filter data
+
+FilterKeepUp_Fini:
+ ; nothing to do
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine FilterKeepUp_GetValue @global
+;
+; @param Y pointer to filter data
+; @return R16 value
+; @clobbers none
+
+FilterKeepUp_GetValue:
+ ldd r16, Y+FILTER_KEEPUP_OFFS_TIMER
+ tst r16
+ breq FilterKeepUp_GetValue_end
+ ldi r16, 1
+FilterKeepUp_GetValue_end:
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine FilterKeepUp_SetValue @global
+;
+; @param Y pointer to filter data
+; @param R16 value
+; @clobbers r17
+
+FilterKeepUp_SetValue:
+ tst r16
+ breq FilterKeepUp_SetValue_end
+ ldd r17, Y+FILTER_KEEPUP_OFFS_RESTARTVALUE
+ std Y+FILTER_KEEPUP_OFFS_TIMER, r17
+FilterKeepUp_SetValue_end:
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine FilterKeepUp_Every100ms @global
+;
+; @param Y pointer to filter data
+; @clobbers r16
+
+FilterKeepUp_Every100ms:
+ ldd r16, Y+FILTER_KEEPUP_OFFS_TIMER
+ tst r16
+ breq FilterKeepUp_Every100ms_end
+ dec r16
+ std Y+FILTER_KEEPUP_OFFS_TIMER, r16
+FilterKeepUp_Every100ms_end:
+ ret
+; @end
+
+
+
+
diff --git a/avr/modules/f_stabilize/0BUILD b/avr/modules/f_stabilize/0BUILD
new file mode 100644
index 0000000..febd367
--- /dev/null
+++ b/avr/modules/f_stabilize/0BUILD
@@ -0,0 +1,11 @@
+
+
+
+
+
+ main.asm
+
+
+
+
+
diff --git a/avr/modules/f_stabilize/main.asm b/avr/modules/f_stabilize/main.asm
new file mode 100644
index 0000000..36bd396
--- /dev/null
+++ b/avr/modules/f_stabilize/main.asm
@@ -0,0 +1,194 @@
+; ***************************************************************************
+; copyright : (C) 2025 by Martin Preuss
+; email : martin@libchipcard.de
+;
+; ***************************************************************************
+; * This file is part of the project "AqHome". *
+; * Please see toplevel file COPYING of that project for license details. *
+; ***************************************************************************
+
+
+; ***************************************************************************
+; defines
+
+.equ FILTER_STABILIZE_OFFS_STATUSBYTE = 0
+.equ FILTER_STABILIZE_OFFS_TIMER = 1
+.equ FILTER_STABILIZE_OFFS_COUNTER = 2
+.equ FILTER_STABILIZE_OFFS_STABLECOUNTVAL = 3
+.equ FILTER_STABILIZE_DATA_SIZE = 4
+
+.equ FILTER_STABILIZE_STATUS_LASTVALUE_BIT = 0
+.equ FILTER_STABILIZE_STATUS_STABLEVALUE_BIT = 1
+.equ FILTER_STABILIZE_STATUS_REPORT0_BIT = 4
+.equ FILTER_STABILIZE_STATUS_REPORT1_BIT = 5
+.equ FILTER_STABILIZE_STATUS_REPEAT0_BIT = 6
+.equ FILTER_STABILIZE_STATUS_REPEAT1_BIT = 7
+
+.equ FILTER_STABILIZE_REPORTTIME1 = 1 ; report after 100ms
+.equ FILTER_STABILIZE_REPORTTIME2 = 11 ; report after 1100ms
+.equ FILTER_STABILIZE_REPORTTIME3 = 22 ; report after 2200ms
+.equ FILTER_STABILIZE_REPEATTIME = 200 ; 20s
+
+
+
+; ***************************************************************************
+; code
+
+.cseg
+
+
+; ---------------------------------------------------------------------------
+; @routine FilterStabilize_Init @global
+;
+; @param Y pointer to filter data
+
+FilterStabilize_Init:
+ clr r16
+ std Y+FILTER_STABILIZE_OFFS_COUNTER, r16
+ std Y+FILTER_STABILIZE_OFFS_STATUSBYTE, r16
+ dec r16
+ std Y+FILTER_STABILIZE_OFFS_TIMER, r16 ; hold timer
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine FilterStabilize_Fini @global
+;
+; @param Y pointer to filter data
+
+FilterStabilize_Fini:
+ ; nothing to do
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine FilterStabilize_GetValue @global
+;
+; Values are reduced to 1 bit (i.e. either "0" or "1").
+;
+; @param Y pointer to filter data
+; @return R19:R18 value
+
+FilterStabilize_GetValue:
+ ldd r18, Y+FILTER_STABILIZE_OFFS_STATUSBYTE
+ lsr r18, FILTER_STABILIZE_STATUS_STABLEVALUE_BIT
+ andi r18, 1
+ clr r19
+ ret
+; @end
+
+
+
+; ---------------------------------------------------------------------------
+; @routine FilterStabilize_SetValue @global
+;
+; The stored value is reduced to 1 bit (i.e. either "0" or "1").
+;
+; @param Y pointer to filter data
+; @param R19:R18 value
+; @clobbers r16, r17
+
+FilterStabilize_SetValue:
+ mov r16, r18
+ or r16, r19
+ breq FilterStabilize_SetValue_set
+ ldi r16, (1<