undefinedWenn jemand auf Toilette war, möchte man danach gerne lüften. Klar, dass vor allem im Winter aber nach 10 Minuten auch wieder zu gemacht werden soll. Leider wurde das bei uns immer wieder vergessen. Da muß es doch eine tolle Lösung geben!

Aber auf eine Recherche im Internet folgte sofort die Ernüchterung. Genau das Passende gibt es nicht. Also muß ich selbst was bauen (Hurra).

Weiter lesen? Klicke die Headline um den ganzen Artikel zu sehen!

Erste Überlegungen

Die erste Idee war ein Reed-Schalter mit Magnet im Fenster. Oder eine Erfassung mit einem Distanz-Sensor? Nach längerem Suchen hat sich aber ein Mikroschalter mit einem langen Hebel als die beste Idee herausgestellt. Und die Steuerung am einfachsten über einen Microprozessor. Da hat sich schnell der Digispark gefunden, der alles hat was ich brauche und sehr günstig zu bekommen ist.

Bauteile

  • Digispark für ca. 2,- EUR
  • Miniatur-Gehäuse für ca. 2,- bis 5,- EUR
  • Mikroschalter mit langem Hebel für ca. 1,- EUR/Stück
  • Ein Summer für ca. 8,- EUR (leider Teuer, gibt aber günstigere)
  • Eine Signalleuchte LED rot, 2,1V, aus meinem Bestand (ca. -,50 EUR)
  • Eine Diode als Verpolungsschutz, aus meinem Bestand
  • Ein Widerstand mit Ohm, aus meinem Bestand
  • Ein Mini-Wippschalter für ca. -,50 EUR

Alles zusammen unter 16,- EUR.

Aufbau

Erstmal geguckt wie das alles in's Gehäuse passen soll und dann müssen die Löcher rein. Ich hab da nicht so lange gefackelt und beherzt drauf los gebohrt. Dann das nervige ausfeilen eines Rechtecks für den Schalter. Das ist die Arbeit die ich am wenigsten mag:

undefined

Dann erstmal gucken wie alles da reinpasst:

undefined

Passt soweit. Jetzt also alles verdrahten und verlöten. Für die LED braucht es einen Vorwiderstand und ich hab noch eine Diode in die Stromversorgung gepackt damit beim anklemmen der Batterie nichts kaputt geht wenn man versehentlich die Pole vertauscht.

Der Digispark bekommt also Strom (9V) wenn sowohl der Wippschalter eingeschaltet ist und auch der Mikroschalter geöffnet ist.

undefined

Nachdem ich mit Schrumpfschlauch die Lötstellen gesichert hab (und mit Isolierband den Digispark von unten isoliert hab) konnte ich alles einsetzen. Den Mikroschalter habe ich mit einer M2.5 Schraube gesichert (durch die Seitenwand). Den Summer mit Doppelklebeband am Boden fixiert.

Damit der Hebel des Mikroschalter korrekt rausguckt hab ich das im Deckel freigesägt (und gefeilt). Der Batterieclip war so groß, dass er auch eine Aussparung brauchte. Ein Loch ist noch dafür da, dass man den Summer gut hört:

undefined

Zusammengebaut schaut es dann so aus:

undefined

Einbau am Fenster

So hab ich das dann an den Boden vom Rolladenkasten geschaubt. Im Fenster fällt auch kaum auf.

undefined  undefined

Links sieht man den Hebel vom Mikrotaster, den ich passend nach unten gebogen habe. Wenn also eingeschaltet ist und das Fenster geöffnet wird, dann wird der Digispark mit Strom versorgt und arbeitet das Programm ab.

Programmcode

Das Programm ist schlicht. Für den coolen Effekt lasse ich die LED Terminator-Like blinken (halber Sinus). Nach 15 Minuten fange ich an zu piepen und nach einer Stunde lass ich es auch wieder.

Den Digispark hab ich in der Arduino-IDE programmiert und auch damit hochgeladen. Ich hab versucht das ein bisschen zu kommentieren damit es auch Anfänger leicht nachvollziehen können.

int led_pin = 1; // LED PIN (Digispark Rev 3.0)
int sum_pin = 0; // Summer PIN

void setup() {
  pinMode(led_pin, OUTPUT); // LED
  pinMode(sum_pin, OUTPUT); // Summer
}

void loop() {
  led();
  beeper();
}

void led() {
  // Lässt die LED cool blinken, unabhängig
  // vom Systemtakt im 50ms-Intervall.
  static float w = 0;
  static unsigned long nextLed = millis();
  if (millis() < nextLed) { return; }
  nextLed = millis() + 50;

  w = w + 0.07;
  if (w > 3.1415) { w = 0; }

  analogWrite(led_pin, sin(w)*255);
}

void beeper() {
  // Kümmert sich um den Summer
  static int counter = 0;
  static int pos = 0;
  static unsigned long nextBeep = millis();
  if (millis() < nextBeep) { return; }
  nextBeep = millis() + 1000;

  // Hier einmal jede Sekunde
  counter = counter + 1;

  if (counter > 1 * 60 * 60) {
    // Nach 1 Stunde ist Schluss!
    digitalWrite(sum_pin, LOW);
    return;
  }
  if (counter > 15 * 60) {
    // Über 15 minuten. Jetzt piepen!
    pos = pos + 1;
    if (pos < 2) {
      // 2 Sekunden Piep
      digitalWrite(sum_pin, HIGH);
    } else {
      digitalWrite(sum_pin, LOW);
    }
    if (pos > 12) {
      // Nach 12 Sekunden (2 Sek Piep,
      // 10 Sek Pause) von vorne
      pos = 0;
      digitalWrite(sum_pin, LOW);
    }
  }
} 

Update

Der Piepser war zu leise mit den 5V (oder 3,3V?) vom Digispark. Daher hab ich einen TIP120 Transistor mit einem 1K Widerstand verwendet um den mit 9V zu beaufschlagen. Er ist jetzt ein wenig lauter :-) Auch die Zeit bis zum Alarm habe ich auf 15 Minuten verlängert. Aber, dass ist natürlich Geruchssache...

Update II

Der Stromverbrauch ist zu viel! Eine normale 9V Batterie hält gerade mal 4 bis 6 Wochen. Da muß was passieren. Ich habe eine gute Webseite gefunden, welche Tipps zur Verbrauchsreduzierung mit dem Digispark gibt. Damit habe ich das überarbeitet.

Das neue Script schickt die CPU immer für eine Sekunde in den Tiefschlaf. Dann wird was gearbeitet und dann wieder geschlafen. Das ändert natürlich auch die Art der Steuerung. Der Tiefschlaf sorgt jetzt aber auch für deutlich weniger Stromverbrauch.

Weiterhin habe ich die LED von PIN 1 auf PIN 2 verlegt. Denn PIN 1 hat auch eine eingebaute LED auf dem Digispark, die immer mit meiner LED mitgeblinkt hat. Das braucht natürlich auch zusätzlich Strom.

Die Nachteile sind, dass der coole Blink-Effekt jetzt einem langweiligen Blinken alle 5 Sekunden gewichen ist. Das wars aber eigentlich auch schon.

Ich werde berichten, wie sich die Laufzeit verändert hat...

Hier der neue Programmcode:

#include <avr/wdt.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
 
#define adc_disable() (ADCSRA &= ~(1<<ADEN)) // disable ADC (before power-off)
#define adc_enable()  (ADCSRA |=  (1<<ADEN)) // re-enable ADC

int led_pin = 2; // LED PIN (Digispark Rev 3.0)
int sum_pin = 0; // Summer PIN

void setup() {
  // Erstmal alle Ports auf INPUT zum Strom sparen
  for (byte i = 0; i < 6; i++) {
    pinMode(i, INPUT);
    digitalWrite(i, LOW);
  }
  // Ausschaltem vom Analog-to-Digital Converter (sparen)
  adc_disable();

  // Benötigte Pins setzen
  pinMode(led_pin, OUTPUT); // LED
  pinMode(sum_pin, OUTPUT); // Summer

  wdt_reset();            // Watchdog reset
  wdt_enable(WDTO_1S);    // Watchdog enable Options:
                          // 15MS, 30MS, 60MS, 120MS, 250MS, 500MS, 1S, 2S, 4S, 8S
  WDTCR |= _BV(WDIE);     // Interrupts watchdog enable
  sei();                  // enable interrupts
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Sleep Mode: max
}

void loop() {
  // Befehle alle 1 Sekunde ausführen
  led();
  beeper();

  // Das folgende schickt die CPU für 1 Sekunde in
  // den Tiefschlaf:
  sleep_enable();
  sleep_cpu();
}

void led() {
  static int lastState = 0;
  if (lastState < 1) {
    digitalWrite(led_pin, HIGH);
  } else {
    digitalWrite(led_pin, LOW);
  }
  
  lastState = lastState + 1;
  if (lastState > 4) {
    lastState = 0;
  }
}

void beeper() {
  static int sekunden = 0;
  static int lastState = 0;
  sekunden = sekunden + 1;

  if (sekunden > 60 * 60) {
    // nach 1 Stunde ist Schluss!
    digitalWrite(sum_pin, LOW);
    return;
  }

  if (sekunden > 15 * 60) {
    // 15 Minuten erreicht. Beep.
    if (lastState < 2) {
      digitalWrite(sum_pin, HIGH);
    } else {
      digitalWrite(sum_pin, LOW);
    }
    lastState = lastState + 1;
    if (lastState > 12) {
      lastState = 0;
    }
  }
}

// Verbinde Watchdog-Timer zum Interrupt zum aufwachen
ISR (WDT_vect) {
  WDTCR |= _BV(WDIE);
}

Was man jetzt noch tun könnte:

  • Die Power-LED vom Digispark entfernen (ich finde die aber praktisch).
  • Die Schutz-Diode auf dem Digispark entfernen.
  • Meine Schutz-Diode entfernen.
  • Statt der 9V Batterie einen Akku mit 3,7V oder 4,2V nutzen und den dann direkt ohne den Digispark Spannungsteiler verwenden. Der hat wohl nur eine Effizienz von ~60% und verbrät vermutlich das meiste.

Mal sehen ob das nötig ist...