Hola.
Creo que acá tus limitaciones son meramente de programación. No lográs abstraer el problema y plasmarlo en un algoritmo que responda a tus requerimientos.
¿Cómo haría yo para lograr lo que necesitás?(lo hago para 48 habitaciones)
Primero: Almacenaría el estado actual de los pulsadores, en un array de 48 bits(6 bytes).Lo llamaré TEMPORAL. Un bit por pulsador. Entonces, un algoritmo debe ir controlando los 3 4067 e ir volcandolos en este arreglo.
Ahora otro array idéntico. Lo llamaré ESTADO, de 48 bits(6 bytes), que almacenen el estado en que se encuentra la habitación(los inicializaría todos a cero, y un 1 indicaría que se ha presionado el pulsador en el pasado de esa habitación).
Una vez finalizado el barrido de los pulsadores, hago una IOR entre los dos array. El resultado de ESTADO IOR TEMPORAL se guarda en ESTADO.
Segundo: cada habitación tiene 1 byte asignado para que cuente cierta unidad de tiempo desde que se presionó el pulsador de dicha habitación.
Entonces acá necesitás un tercer array de 48 bytes.Lo llamaré, TIEMPO, y debería ser inicializado todo a cero.
Tercero: Un algoritmo que cuente tiempo. Yo voy a elegir períodos de 1 segundo. Para esto vas a tener que usar un timer y un registro auxiliar probablemente. Supongamos que el timer interrumpe cada 50ms. Entonces con un registro auxiliar(lo llamaré VEINTEAVOSEG) contarás 20 veces para lograr un segundo. Pero lo seguiría haciendo contar hasta 200. Lo usaría como doble timer. Contando lapsos de 1 segundo y de 10 segundos.
Entonces, hago VEINTEAVOSEG MOD(% en CCS) 200.Si eso da 0, entonces transcurrieron 10 segundos. Si esto es cierto, hago que VEINTEAVOSEG vuelva a valer 0 para volver a contar y además, recorro el array ESTADO de los pulsadores. Si un bit del array ESTADO está en 1,incremento el elemento del array TIEMPO asociado en una unidad(siempre teniendo cuidado de que no desborde. Si el elemento del array TIEMPO vale 255, no lo incremento.Lo dejo en 255).
Luego si haciendo VEINTEAVOSEG MOD 20 obtengo 0, he contado un segundo.Entonces, invierto el valor de un flag(1 bit) que llamaré LED_ON_OFF.
Cuarto: El algoritmo que lo une todo. Si VEINTEAVOSEG MOD 20 dió cero, entonces es hora de refrescar los LEDs.
Recorro uno a uno los elementos(bits) del array ESTADO. Si está en 0, envío un cero al LED asociado. Si está en 1, entonces:
Compruebo el valor del elemento correspondiente del array TIEMPO. Si su valor excede un valor prefijado(Digamos, por ejemplo: 60(60*10 = 600 segundos=10 min) entonces, lo enciendo si LED_ON_OFF está en 1, lo apago si LED_ON_OFF está en 0.
Si su valor no excede dicho valor prefijado. Enciendo el LED.
El barrido de los LEDS y posterior análisis es lo único que tendrías dentro de un bucle. Lo otro sucedería con interr, pero como te conviene priorizar la deteccion de los pulsadores, desactiva las interr globales antes del barrido y volve a activarlas al terminar el análisis. Total, el error de tiempos que te genera es infimo.
El botón de RESET pone a cero el array TIEMPO y ESTADO. En máximo un segundo, deberían apagarse todas las luces.
¿Capiche?
Saludos.