Cross check required

The code is ready, but I’m well advised to ask you for review.
It is still unclear to me why the timer does not call - as defined - after expiration the function readAgain,
but only over the test isActive.
If you still have suggestions for my ToDos fire free :wink:
In fact, this example can also be adapted to all sorts of open windows/doors. Take it with a smile.

// Reed-Switch with Particle Photon and a buzzer - works with v0.7.0-rc.3 without Libaries
// Ingo Lohs, v1.0 v. 16.11.2017
// Project to indicate a beep on an open toilet lid
// it is more of an educational measure not to block the toilet from the masses

// ToDo:
// * how often was the toilet used? Particle.Publish, counter
// * how long was the lid actually open (measurement of time)
// * why is it necessary to check an active timer, why does not it jump to the readAgain function after the timer expires?

    #include "application.h"                     // necessary when using Timer

    const int REED_PIN_IN = D2;                  // Pin connected to reed switch
    const int REED_PIN_OUT = D4;                 // Pin connected to reed switch
    const int BUZZER_PIN_OUT = A4;               // Pin connected to a buzzer and to GND // On the Photon, P1 and Electron, this function works on pins D0, D1, D2, D3, A4, A5, WKP, RX and TX
    const int LED_PIN = D7;                      // Pin internal LED 
    const int standard_toilette_session = 10000; // how many seconds is your standard time for you? (= 10 seconds) 

    unsigned long lastmillis = 0;                // time for iteration the loop

    Timer timer(standard_toilette_session, readAgain); // https://docs.particle.io/reference/firmware/photon/#software-timers

    // **************

    void setup() 
    {
      Serial.begin(9600);
      pinMode(REED_PIN_IN, INPUT);
      pinMode(REED_PIN_OUT, OUTPUT);
      pinMode(LED_PIN, OUTPUT);
      pinMode(BUZZER_PIN_OUT, OUTPUT);
    }

    // **************

    void loop() 
    {
        if ((millis() - lastmillis) > 1000) {
            lastmillis = millis();
            readData();
        }
    }

    // **************

    void readData() 
    {

        int proximity = digitalRead(REED_PIN_IN); // Read the state of the switch
        
            if (proximity == HIGH) // If the pin reads HIGH, the switch is open // the pin reads LOW, the switch is closed
            {
            Serial.println(">> Session begin >> Switch is open");  
            // Particle.publish("Toilette", "toilet is in use right now", PRIVATE); // now the Particle Cloud knows that you have gone to the toilet
            // timer starts
            timer.start(); // https://docs.particle.io/reference/firmware/photon/#start-

              // At the end of the expiring timer reset the timer and call the function readAgain
              if (timer.isActive() == false) // https://docs.particle.io/reference/firmware/photon/#isactive--1
              { 
                   timer.reset();
                   readAgain();
              }
              
            }
            else if (proximity == LOW) 
            {
            Serial.println(">> normal Status >> Switch is closed");
            timer.stop(); // stops a running timer.
            digitalWrite(LED_PIN, LOW); // Turn the LED off
            }
            else
            {
            Serial.println("Switch ERROR Reading Value");
            timer.stop(); // stops a running timer.
            digitalWrite(LED_PIN, LOW); // Turn the LED off
            }
    }

    // ************** At the end of the expiring timer, the open lid is checked again

    void readAgain()
    {
                int lid_open = digitalRead(REED_PIN_IN); // Read the state of the switch
                if (lid_open == HIGH)
                // ALARM // the user reads newspaper or something else and blocks the toilet or in the worst case does not close the lid
                {
                    digitalWrite(LED_PIN, HIGH); // Turn the LED on - optical warning
                    // Particle.publish("Toilette", "forgot to close the lid", PRIVATE); // the Particle Cloud knows what you not learned
                    // Buzzer on - accustical warning
                        // notes in the melody:
                        // https://docs.particle.io/reference/firmware/photon/#tone-
                        int melody[] = {1908,2551,2551,2273,2551,0,2024,1908}; //C4,G3,G3,A3,G3,0,B3,C4
                        // note durations: 4 = quarter note, 8 = eighth note, etc.:
                        int noteDurations[] = {4,8,8,4,4,4,4,4};
                        // iterate over the notes of the melody:
                        for (int thisNote = 0; thisNote < 8; thisNote++)  
                        {
                        // to calculate the note duration, take one second
                        // divided by the note type.
                        //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
                        int noteDuration = 1000/noteDurations[thisNote];
                        tone(BUZZER_PIN_OUT, melody[thisNote], noteDuration);
                        // to distinguish the notes, set a minimum time between them.
                        // the note's duration + 30% seems to work well:
                        int pauseBetweenNotes = noteDuration * 1.30;
                        delay(pauseBetweenNotes);
                        // stop the tone playing:
                        noTone(BUZZER_PIN_OUT);
                        }  
                        // the annoying melody is played continuously until the lid is closed
                }
                else
                // all is fine // the user closed the lid during the defined delay time
                {
                    digitalWrite(LED_PIN, LOW); // Turn the LED off 
                    noTone(BUZZER_PIN_OUT);     // Turn the Buzzer off
                }
    }

Could it be that you keep restarting the timer before it times out?
Whenever proximity == HIGH you call timer.start(), this causes it to reset.
https://docs.particle.io/reference/firmware/photon/#start-

With proximity == high it is checked if the reed switch (the toilet lid) is open: if so, may the timer let some time elapse (standard_toilette_session - 10 seconds in the example), then call the function readAgain to alarm beat.
In my opinion, I have activated the first start of the timer with timers.start().
But yes, in my circuit I get an alarm sound immediately after opening the switch.
I can not say why and what I have to change.

Do I think wrong: would a delay (standard_toilette_session) have been sufficient?

instead of continually acting when the sensor is HIGH, instead start your timer when the sensor becomes HIGH

I can not tell on which position I’m starting the timer, so after its expiry, a check on the open switch takes place.

#include "application.h"                     // necessary when using Timer

const int REED_PIN_IN = D2;                  // Pin connected to reed switch
const int REED_PIN_OUT = D4;                 // Pin connected to reed switch
const int BUZZER_PIN_OUT = A4;               // Pin connected to a buzzer and to GND // On the Photon, P1 and Electron, this function works on pins D0, D1, D2, D3, A4, A5, WKP, RX and TX
const int LED_PIN = D7;                      // Pin internal LED 
const int standard_toilette_session = 10000; // how many seconds is your standard time for you? (= 10 seconds) 

unsigned long lastmillis = 0;                // time for iteration the loop

Timer timer(standard_toilette_session, readData); // https://docs.particle.io/reference/firmware/photon/#software-timers

// **************

void setup() 
{
  Serial.begin(9600);
  pinMode(REED_PIN_IN, INPUT);
  pinMode(REED_PIN_OUT, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUZZER_PIN_OUT, OUTPUT);
  
  //timer.start();
}

// **************


void loop() 
{
    if ((millis() - lastmillis) > 1000)
    {
      lastmillis = millis();
        timer.start();
    }
}


// ************** 

void readData()
{
            int lid_open = digitalRead(REED_PIN_IN); // Read the state of the switch
            if (lid_open == HIGH)
            // ALARM // the user reads newspaper or something else and blocks the toilet or in the worst case does not close the lid
            {
                digitalWrite(LED_PIN, HIGH); // Turn the LED on - optical warning
                // Particle.publish("Toilette", "forgot to close the lid", PRIVATE); // the Particle Cloud knows what you not learned
                // Buzzer on - accustical warning
                   // code for buzzer
            }
            else
            // all is fine // the user closed the lid during the defined delay time
            {
                digitalWrite(LED_PIN, LOW); // Turn the LED off 
            }
}

You are starting/resetting the timer every second, so I still doubt it’ll expire anytime.

I took up the idea of BulldogLowell and pushed the timer into the setup().
This has the advantage to omit the loop() and had an abbreviation of the code to follow.
Thx gentlemen!