Arbeitsweise vom sketch

Hallo an alle

Ich habe mir vor ein paar Tagen in unsern Heizugskeller ein Abluftsystem eingebaut.

Es ist nur ein Lüfter (12 Volt) der ins Freie geht. Daraufhin habe ich mit einem Arduino, PIR Sensor und einem Relay eine kleine Schaltung gebaut. Durch Zufall bin ich dann auf den sketch gestossen und habe ihn dann aufgebaut.Der sketch läuft auch aber ich verstehe den Ablauf des sketch nicht. Kann mir mal Bitte einer sagen wie der sketch arbeitet. Wenn ich den Serial Montior öffne fängt er immer an von 30 runterzuzählen und hört dann bei 28 auf, und das gleiche geht von vorne los.

Danke Stefan

#include "Countimer.h" //Countdown timer library
 
const byte bootingLed = 4;
const byte notDetectedLed = 5;
const byte detectedLed = 6;
const byte buzzer = 7;
const byte relay = 8;

 
//TIMER FOR BUZZER INTERVALS
unsigned long previousMillis = 0; 
 
const byte interruptPIRLow = 2; // Interrupt pin to trigger when motion sensor goes low
const byte interruptPIRHigh = 3; // Interrupt pin to trigger when motion sensor goes high
 
//TIMER BUZZES EVERY 30 SECONDS
const long INTERVAL = 1000;
 
Countimer onDelayTimer;  //Initialialize a new instance of the Countimer object for on-delay (delay before relay is turned on)
Countimer offDelayTimer; //Initialialize a new instance of the Countimer object for off-delay (delay before relay is turned off)
 
void counter();  
void bootSystem();   //Allows the PIR sensor sometime to boot up and start giving stable reading
void displayTimerCount();  //Displays current time left in the count down timer in serial monitor
void checkRelayStatus(); //Checks if relay is already on or off
void beepbuzzer(); //Beeps the buzzer
void switchRelayON();
void switchRelayOFF();
 
void setup(){
 
  Serial.begin(9600);
  pinMode(relay, OUTPUT);
  pinMode(bootingLed, OUTPUT);
  pinMode(detectedLed, OUTPUT);
  pinMode(notDetectedLed, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(interruptPIRLow, INPUT_PULLUP);
  pinMode(interruptPIRHigh, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPIRLow), checkRelayStatusOFF, FALLING);  //Set an interrupt which is triggered when PIR sensor goes from High to low
  attachInterrupt(digitalPinToInterrupt(interruptPIRHigh), checkRelayStatusON, RISING); //Set an interrupt which is triggered when when PIR sensor goes from low to high
 
  onDelayTimer.setCounter(0, 0, 30, onDelayTimer.COUNT_DOWN, switchRelayON); //Set a 30 second countdown timer as a delay before switching on relay when motion is detected
  onDelayTimer.setInterval(displayOnDelayTimerCount, 1000);  //Display the time left in the countdown every 1 second
 
  offDelayTimer.setCounter(0, 5, 00, offDelayTimer.COUNT_DOWN, switchRelayOFF); //Set a 30 second countdown timer as a delay before switching off relay when no motion is detected
  offDelayTimer.setInterval(displayOffDelayTimerCount, 1000); //Display the time left in the countdown every 1 second
  
 bootSystem();  //Delay for 60 seconds to allow PIR sensor to start giving stable values
}
 
void loop(){
    unsigned long currentMillis = millis();
    onDelayTimer.run();  //Initialize the onDelayTimer function
  offDelayTimer.run(); //Initialize the offDelayTimer function
 
  if( !offDelayTimer.isCounterCompleted()){ 
 
    if (currentMillis - previousMillis >= INTERVAL) {
    previousMillis = currentMillis;
    digitalWrite(buzzer, HIGH);
    delay(500);
    digitalWrite(buzzer, LOW);
  }
 
  }
}
 
//BOOT THE SYSTEM
void bootSystem(){
  Serial.println("System is booting...Wait for 1 minute");
  digitalWrite(bootingLed, HIGH);  //Turn booting LED (blue LED) on while system is booting
  delay(10000);
  digitalWrite(bootingLed, LOW);
    digitalWrite(notDetectedLed, HIGH);   //Turn NOT Dected LED on (red led) after system finished booting
    Serial.println("Booting Complete...");
 
}
 
/* =====================================================================
 CHECK IF THE RELAY IS ON AND START ON-DELAY COUNTDOWN TIMER IF IT ISNT.
 ======================================================================*/
void checkRelayStatusON(){
  Serial.println("Motion Detected. Low To High Interrupt Triggered");
  digitalWrite(notDetectedLed, LOW);
  digitalWrite(detectedLed, HIGH);
 
  //CHECK IF OFF-DELAY COUNTDOWN TIMER WAS RUNNING WHILE MOTION WAS DETECTED AND STOP IT 
  if(!offDelayTimer.isCounterCompleted()){ 
    Serial.println("Stopping OFF Delay Timer now...");
    offDelayTimer.stop();  //STOP THE OFF DELAY TIMER
    if(offDelayTimer.isStopped()){
      Serial.println("Successfully Stopped OFF delay Timer");
    }
    else{
      Serial.println("Error Stopping Off-Delay Timer");
    }
  }
 
  //CHECK IF THE RELAY IS OFF AND TURN IT ON IF IT ISNT
  if(digitalRead(relay)==LOW){
     Serial.println("checkRelayStatusON Results: Relay is OFF...");
    startOnDelayTimer();
  }
  else{
      Serial.println("checkRelayStatusON Results: Relay is on ON... No further action");
  }
}
 
//CHECK IF THE RELAY IS OFF AND START OFF DELAY COUNTDOWN TIMER IF IT ISNT.
void checkRelayStatusOFF(){
  Serial.println("Motion Not Detected Anymore. High to low Interrupt Triggered");
  digitalWrite(detectedLed, LOW);
  digitalWrite(notDetectedLed, HIGH);
 
    //CHECK IF ON-DELAY COUNTDOWN TIMER WAS RUNNING WHILE MOTION WAS NOT DETECTED ANYMORE AND STOP IT 
  if(!onDelayTimer.isCounterCompleted()){ 
    Serial.println("Stopping ON Delay Timer now...");
    onDelayTimer.stop();  //STOP THE OFF DELAY TIMER
    if(onDelayTimer.isStopped()){
      Serial.println("Successfully Stopped ON delay Timer");
    }
    else{
      Serial.println("Error Stopping ON-Delay Timer");
    }
  }
 
  if(digitalRead(relay)==HIGH){
    Serial.println("checkRelayStatusOff Results: ON...");
    startOffDelayTimer();
  }
  else{
    Serial.println("checkRelayStatusOff Results: OFF...No further action");
  }
}
 
//START 15 SECOND ON DELAY COUNTDOWN TIMER AND TURN ON RELAY AFTER COUNTDOWN GOES TO ZERO
void startOnDelayTimer(){
  Serial.println("Starting OnDelay Timer...");
  digitalWrite(notDetectedLed, LOW); //Change LED statuses
  digitalWrite(detectedLed, HIGH);
  offDelayTimer.stop();
  onDelayTimer.start();
}
 
//START 30 SECOND OFF DELAY COUNTDOWN TIMER AND TURN OFF RELAY AFTER COUNTDOWN GOES TO ZERO
void startOffDelayTimer(){
  Serial.println("Starting OffDelay Timer...");
  digitalWrite(notDetectedLed, HIGH); //Change LED statuses
  digitalWrite(detectedLed, LOW);
  onDelayTimer.stop();
  offDelayTimer.start();
}
 
//SWITCH ON RELAY AFTER COUNTDOWN
void switchRelayON(){
  Serial.println("Turning relay on...");
  digitalWrite(relay, HIGH);
  if(digitalRead(relay)==HIGH){
    Serial.println("Relay successfully turned ON");
  }
  else{
     Serial.println("Switching ON relay FAILED...");
  }
}
 
//SWITCH OFF RELAY AFTER COUNTDOWN
void switchRelayOFF(){
  Serial.println("Turning relay off...");
  digitalWrite(relay, LOW);
    if(digitalRead(relay)==LOW){
    Serial.println("Relay successfully turned OFF");
  }
  else{
     Serial.println("Switching OFF relay FAILED...");
  }
}
 
//DISPLAY COUNTDOWN TIMER
void displayOnDelayTimerCount()
{
  Serial.print("Time To Switch On: ");
  Serial.println(onDelayTimer.getCurrentTime());
}
 
void displayOffDelayTimerCount()
{
  Serial.print("Time To Switch Off: ");
  Serial.println(offDelayTimer.getCurrentTime());
}

Hi

Was soll der Müll äh, Sketch, eigentlich machen?
Warum 'bootet' der Arduino und warum benötigt man für so schnarchlahmes Zeug wie einen Sekundentimer (Dessen Sinn ich ebenfalls nicht gefunden habe) einen Interrupt?

Dann wären noch einige Kleinigkeiten von Interesse:
Woher ist der Sketch?
Wo bekomme ich die dort benutzte Lib, damit ich, zumindest theoretisch, den Sketch testen könnte?

MfG

Muss ein spezieller Spezial_PIR sein wenn der 1 Minute Bootzeit braucht.

Ach so, Lüfter wird aktiviert wenn jemand den Raum betritt oder wie soll das werden?

Klaus_ww:
Ach so, Lüfter wird aktiviert wenn jemand den Raum betritt oder wie soll das werden?

Sieht so aus, wenn ich mir das hier durchlese.
Hat also mit einer Abluftsteuerung nichts zu tun.

This project uses the HC-SR504 PIR Motion sensor to detect the presence of people in a room and automatically switches a connected load on or off. You can connect any load to it, for instance, an Air conditioner.

Hi

Wenn der Sketch von dieser 'Schmiede' ist - Die haben noch gaaanz andere Dinge auf Lager:
USB-LED

  • 16 LED ohne eigene Strombegrenzung parallel
  • USB-Port immerhin mit 10Ω 'strombegrenzt', sollte selbst beim GAU 500mA einhalten (bis der R durchgeröstet ist)
    ... ist halt die Frage, wie lange der Kram halten soll.

Meiner Ansicht nach: Finger weg von der Seite, Die hätten wohl selbst Probleme einen Eimer Wasser umzutreten ...

MfG

Hallo an alle
Ist das jetzt ein PIR Sensor oder ein Ultraschallsensor.
Laut Googel ist der Typ HC-SR504 PIR Motion ein Ultraschallsensor .

@postmaster-ino

Von da ist die Lib GitHub - inflop/Countimer: This is simple timer and counter Arduino library.

@Moko

Ja von da ist der sketch.

@Klaus_ww

Ja Klaus es ist so wie du schreibst . Ja will wenn ich den Heizraum betrete das der Lüfter einschaltet,

und wenn ich gehe das der Lüfter noch ein paar Minuten nachläuft. Denn wir Heizen mit Scheitholz.

Wir verheizen im Winter ca 25 bis 30 Raummeter Holz. Und deswegen kann ich immer im Frühjahr den

Heizraum saubermachen . Und deswegen der Lüfter

Hi

Muß es dieser Sketch sein?
Wie Du meinen bisherigen Ausführungen entnehmen kannst, bin ich weder von dem Sketch, dem eventuell darin vergrabenem Sinn, noch der Quelle großartig begeistert :wink:

Alternativ:
In loop() guckst Du, ob der Sensor GERADE JETZT aktiv ist -> Uhrzeit merken (lastseen).
Wenn Lüfter == AUS && millis()-lastseen<laufzeit --> Lüfter AN
Wenn Lüfter == AN && millis()-lastseen>=laufzeit --> Lüfter AUS

Wenn Du 49 Tage nicht im Keller warst, wird der Lüfter eine Laufzeit AN sein, sonst sollten die drei Zeilen ziemlich genau Dein Problem umschreiben.

Weil der Arduino hierbei NICHTS zu tun hat, könnte man noch Raumwerte erfassen und per Funk in die Gegend strahlen - interessiert's, ob's im Keller gerade muffig wird?
Da könnte der Arduino dann ebenfalls den Lüfter aktivieren, außerhalb der Anwesenheit von Personal.

MfG

Hallo postmaster-ino

Nein es muss nicht der Sketch sein.

Aber da ich zu wenig Ahnung von Elektronik und Programmieren habe schaue ich mich halt immer bisschen um.

Ich mache das nur als Hobby wenn ich halt mal was brauche.

Danke Stefan

Hi

Ich denke, die Wenigsten hier machen 'Arduino' (oder überhaupt Was in diese Richtung) beruflich - somit bleibt nur Hobby (oder ... Hausaufgabe g).
An wenig Ahnung kann man schrauben, viel mehr als Vorwiderstände für LEDs werden auch nicht berechnet - der Rest ist Bauch/Glückssache :wink: (Für Transistor bin ich zu blöd und beim FET ist der Widerstand unkritisch)
Programmieren ist dann wieder Richtung Logik - WAS muß WANN passieren, damit ich an MEIN ZIEL komme - Darin bin ich, so denke ich, halbwegs geschickt - wobei ich eher Kindergarten bin, wenn ich die anderen Diskussionen hier mitverfolge.

Zu meinem Drei-Zeiler in #7 wäre eine Ausarbeitung ala Nachtwächter (combie nennt Ihn 'Wachmann' in Seiner Liste) Deinerseits 'nett', daß erkennbar wird, daß Du Das doch schon selber irgendwie erschlagen willst.
Klar ist Das für 'uns Cracks' kein großer Aufriss, Das soll für Dich aber auch so werden!
Auch kannst Du wesentlich einfacher/schneller/erfolgreicher eigene Ideen umsetzen, wenn das Programm von Dir ist und nicht nur C&P aus den Tiefen des WWW - wie man an dem von Dir gefundenem Sketch schön sehen kann - selbst wir müssen uns DA rein denken aber nur, um etwas recht Einfacheres möglichst kompliziert zu machen, fehlt mir akut der Elan.
Wie geschrieben, meiner Meinung braucht's Dafür keine Lib und keinen (eigenen) Interrupt.

Wenige IF-Zeilen oder ein switch-case-Block, hier und Da die Uhrzeit (aka millis() ) merken oder Prüfen und der Lüfter kann Seine Aufgabe übernehmen.

MfG

Als Anfänger sollte man den Sketch nur als negativ Beispiel ansehen, da ist einfach so viel falsch in dem Sketch:

void checkRelayStatusON(){ //Interrupt
  Serial.println("Motion Detected. Low To High Interrupt Triggered");
}

Für solche Sachen braucht man keine Interrupts, man liest Pins einfach wiederholt in der loop() aus, eventuell auch mit Flankenerkennung.
Serial in Interrupts geht ja mal garnicht, genauso wie delay. Ein Interrupt sollte schnelsstmölich verlassen werden.

digitalWrite(relay, LOW);
    if(digitalRead(relay)==LOW){
    Serial.println("Relay successfully turned OFF");
  }
  else{
     Serial.println("Switching OFF relay FAILED...");
  }

Warum sollte man sowas überprüfen?

Programmiere dein Programm lieber selbst von Grund auf, verwende auch keine Codeschnipsel aus dem Sketch dieser Seite, damit lernst du nur falsche Dinge.

Hi

... wenn das Relay dort nicht auch Low-Activ ist ...
Auch, wenn der µC Seinen Pin auf LOW schaltet, wird Dieser aktiv auf LOW gezogen - wenn jetzt - egal wer - den Pin oben halten möchte, stirbt irgend was - spätestens dann ist der µC Geschichte, oder das Signal definitiv jetzt LOW :wink:

Jupp, die Seite hat schon tolle Beispiele ...

MfG

PS: bitte den ganzen Thread lesen - in diesem Post könnte die ein oder andere Portion Ironie enthalten sein ... besonders im Satz vor dem MfG ...

Verzweifler:

    if(digitalRead(relay)==LOW){

Serial.println("Relay successfully turned OFF");
 }
 else{
    Serial.println("Switching OFF relay FAILED...");
 }



Warum sollte man sowas überprüfen?

Die Idee, sein Relais zu überprüfen, ist schon gut. Mach ich stellenweise auch. Aber die Ausführung ist halt nicht zu Ende gedacht. Ich frage einen weiteren Kontaktsatz des Relais über einen anderen Pin ab. Dann weiss ich wenigstens, dass das Relais tatsächlich angezogen hat und nicht eine Sicherung durch ist.

ElEspanol:
Die Idee, sein Relais zu überprüfen, ist schon gut. Mach ich stellenweise auch. Aber die Ausführung ist halt nicht zu Ende gedacht. Ich frage einen weiteren Kontaktsatz des Relais über einen anderen Pin ab. Dann weiss ich wenigstens, dass das Relais tatsächlich angezogen hat und nicht eine Sicherung durch ist.

Ja, dein Weg macht auch Sinn, aber einen Pin überprüfen, den man eben gesetzt hat macht keinen Sinn. Genauso unnötig könnte man z.B. Den Wert einer Variable ändern und danach überprüfen, ob die Änderung geklappt hat.

Verzweifler:
Ja, dein Weg macht auch Sinn, aber einen Pin überprüfen, den man eben gesetzt hat macht keinen Sinn. Genauso unnötig könnte man z.B. Den Wert einer Variable ändern und danach überprüfen, ob die Änderung geklappt hat.

Ich befürchte, du hast die Antwort von EIEspanol nicht verstanden.

Er fragt mit einem zusätzlichen Pin einen weiteren Relaiskontakt ab, nicht den Pin selbst.