diff --git a/avr/modules/0BUILD b/avr/modules/0BUILD
index 8c898bc..2ff0e01 100644
--- a/avr/modules/0BUILD
+++ b/avr/modules/0BUILD
@@ -23,6 +23,7 @@
ma_light
motion
uart_bitbang
+ tcrt1000
diff --git a/avr/modules/tcrt1000/0BUILD b/avr/modules/tcrt1000/0BUILD
new file mode 100644
index 0000000..febd367
--- /dev/null
+++ b/avr/modules/tcrt1000/0BUILD
@@ -0,0 +1,11 @@
+
+
+
+
+
+ main.asm
+
+
+
+
+
diff --git a/avr/modules/tcrt1000/main.asm b/avr/modules/tcrt1000/main.asm
new file mode 100644
index 0000000..7732912
--- /dev/null
+++ b/avr/modules/tcrt1000/main.asm
@@ -0,0 +1,189 @@
+; ***************************************************************************
+; copyright : (C) 2023 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. *
+; ***************************************************************************
+
+
+
+.equ TCRT1K_INTERVAL = 7
+.equ TCRT1K_LIMIT = 170
+
+.equ TCRT1K_STATE_OPEN = 255
+.equ TCRT1K_STATE_CLOSED = 0
+
+.equ TCRT1K_FLAGS_REPORT_CHANGE_BIT = 0
+
+
+; ***************************************************************************
+; data
+
+.dseg
+
+tcrt1kDataBegin:
+ tcrt1kTimer: .byte 1
+ tcrt1kLastState: .byte 1
+ tcrt1kLastValue: .byte 1
+ tcrt1kStateCounter: .byte 1
+ tcrt1kFlags: .byte 1
+tcrt1kDataEnd:
+
+
+
+
+; ***************************************************************************
+; code
+
+.cseg
+
+
+
+; ---------------------------------------------------------------------------
+; @routine TCRT1K_Init
+;
+; Init module.
+;
+; @return CFLAG always set
+
+TCRT1K_Init:
+ ; preset SRAM data area
+ ldi xh, HIGH(tcrt1kDataBegin)
+ ldi xl, LOW(tcrt1kDataBegin)
+ clr r16
+ ldi r17, (tcrt1kDataEnd-tcrt1kDataBegin)
+ rcall Utils_FillSram
+
+ ; setup pins
+ sbi TCRT1K_LED_DDR, TCRT1K_LED_PIN ; set DATA port as output
+ cbi TCRT1K_LED_PORT, TCRT1K_LED_PIN ; LED off
+ cbi TCRT1K_ADC_PORT, TCRT1K_ADC_PIN ; disable internal pullup for ADC
+ cbi TCRT1K_ADC_DDR, TCRT1K_ADC_PIN ; set ADC port as input
+
+ ldi r16, TCRT1K_ADC_MUX ; select input pin, use Vcc as reference voltage
+ out ADMUX, r16
+ ldi r16, (1 << ADLAR)
+ out ADCSRB, r16
+ ldi r16, (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0) ; enable, prescaler 8
+ out ADCSRA, r16
+
+ ldi r16, TCRT1K_INTERVAL
+ sts tcrt1kTimer, r16
+
+ sec
+ ret
+
+
+
+TCRT1K_Fini:
+ sec
+ ret
+
+
+
+TCRT1K_Every100ms:
+ lds r16, tcrt1kTimer
+ dec r16
+ breq TCRT1K_Every100ms_readValue
+ sts tcrt1kTimer, r16
+ cpi r16, 2
+ breq TCRT1K_Every100ms_ledOn
+ cpi r16, 1
+ breq TCRT1K_Every100ms_startMeasure
+ ret
+TCRT1K_Every100ms_ledOn:
+ sbi TCRT1K_LED_PORT, TCRT1K_LED_PIN ; LED on
+ ret
+TCRT1K_Every100ms_startMeasure:
+ sbi ADCSRA, ADSC ; start conversion
+ ret
+TCRT1K_Every100ms_readValue:
+ sbic ADCSRA, ADSC
+ ret ; return if bit still set, leave tcrt1kTimer at "1"
+ ; conversion complete, read value
+ ldi r16, TCRT1K_INTERVAL ; restart timer
+ sts tcrt1kTimer, r16
+ in r16, ADCH ; read value from ADC
+ cbi TCRT1K_LED_PORT, TCRT1K_LED_PIN ; LED off
+ sts tcrt1kLastValue, r16
+
+ cpi r16, TCRT1K_LIMIT
+ ldi r16, TCRT1K_STATE_CLOSED
+ brcs TCRT1K_Every100ms_checkChange
+ ldi r16, TCRT1K_STATE_OPEN
+TCRT1K_Every100ms_checkChange:
+ lds r17, tcrt1kLastState
+ cp r16, r17
+ brne TCRT1K_Every100ms_stateChanged
+ lds r16, tcrt1kStateCounter
+ inc r16
+ brne TCRT1K_Every100ms_incStateCounter
+ ret
+TCRT1K_Every100ms_incStateCounter:
+ sts tcrt1kStateCounter, r16
+ cpi r16, 1 ; report change after one interval
+ breq TCRT1K_Every100ms_reportChange
+ cpi r16, 2 ; report change after two intervals
+ breq TCRT1K_Every100ms_reportChange
+ cpi r16, 10 ; report change after two intervals
+ breq TCRT1K_Every100ms_reportChange
+ ret
+TCRT1K_Every100ms_reportChange:
+ lds r16, tcrt1kFlags
+ ori r16, (1<