/* ΓΕΝΙΚΕΣ ΟΔΗΓΙΕΣ Ο κώδικας δεν είναι πλήρης :) Υπάρχουν κενά τα οποία συμπληρώνετε με κριτήριο το τι θέλετε να κάνει η ΔΙΚΗ ΣΑΣ εφαρμογή. Διαβάζετε τις οδηγίες που υπάρχουν μέσα στον κώδικα, κάνουν καλό :) */ // Ο αισθητήρας κίνησης είναι λίγο παράξενος :) // Κανονικά θα αρκούσε ένας κώδικας του τύπου "Διάβασε τιμή αισθητήρα, // αν είναι high τότε υπάρχει κινηση, αν είναι low τότε δεν υπάρχει κίνηση." // Κάτι δηλ. πολύ παρόμοιο με ένα ψηφιακό button - Δείτε τον αντίστοιχο κώδικα. // Ωστόσο, λόγω ποιοτικής κατασκευής ο αισθητήρας δεν είναι τόσο αξιόπιστος. // Άρα δείτε τον κώδικα που υπάρχει πιο κάτω και τις εξηγήσεις που δίνονται. // Και θα πρότεινα να τον δοκιμάσετε. Ουσιαστικά ανάβει το led 13 όταν δει κίνηση. // Αν σας φαίνεται τρομερά πολύπλοκο, τότε να χρησιμποιήσετε την λογική του button, // αποδεχόμενοι το γεγονός ότι ο σένσορας δεν θα λειτουργεί και τόοοοοσο καλά. // O PIR sensor χρειάζεται περίπου 10-60 sec για calibration int calibrationTime = 30; // O PIR sensor θα συνδεθεί στο pin 4 (output pin) int pirPin = 4; // H έξοδος του PIR γίνεται HIGH όταν ανιχνεύει κίνηση. // Ωστόσο, ακόμη κι αν υπάρχει κίνηση, ο σένσορας δίνει κατά διαστήματα LOW // δίνοντας έτσι την εντύπωση ότι δεν ανιχνεύει κίνηση. Το πρόβλημα αυτό // διορθώνεται με μέτρηση του χρονικού διαστήματος κατά το οποίο ο σένσορας // δίνει LOW. Αν το διάστημα αυτό είναι μικρότερο από 5sec θεωρούμε ότι // η κίνηση δεν έχει σταματήσει. long unsigned int pause = 5000; // H μεταβλητή lockLow είναι true όταν αναμένουμε ο PIR να δώσει HIGH. // Όταν δηλ ο PIR δίνει σταθερά LOW, που σημαίνει ότι είμαστε βέβαιοι ότι δεν // ανιχνεύει κίνηση, τότε το lockLow είναι true. // Αν είμαστε σε φάση που έχει δώσει LOW και μετράμε τον χρόνο για να δούμε // αν πρόκειται όντως για παύση κίνησης, τότε το lockLow είναι false. boolean lockLow = true; boolean takeLowTime; // H μεταβλητή lowIn αποθηκεύει τη χρονική στιγμή κατά την οποία // o PIR δίνει LOW μετά από HIGH. Ουσιαστικά, την αρχή κάθε φάσης LOW. long unsigned int lowIn; // Χρησιμοποιούμε το led 13 για debug (δοκιμές) int ledPin = 13; /***************************************************************************/ /* SETUP */ /***************************************************************************/ void setup() { // αρχικοποίηση σειριακής επικοινωνίας Serial.begin(9600); // ορίζουμε ως input, output τα pins για τον PIR και το led αντίστοιχα. pinMode(pirPin, INPUT); pinMode(ledPin, OUTPUT); // αρχικοποίηση του PIR pin digitalWrite(pirPin, LOW); // καθυστέρηση ώστε να προλάβει ο PIR να κάνει calibrate Serial.print("calibrating sensor "); for (int i = 0; i < calibrationTime; i++) { Serial.print("."); delay(1000); } Serial.println(" done"); Serial.println("SENSOR ACTIVE"); delay(50); } /***************************************************************************/ /* LOOP */ /***************************************************************************/ void loop() { if (digitalRead(pirPin) == HIGH) { // O PIR ανιχνεύει κίνηση. // Ανάβει το led 13 για να δείξει ότι ο PIR έδωσε HIGH. digitalWrite(ledPin, HIGH); if (lockLow == true) { // Η μεταβλητή lockLow είναι true όταν ο PIR είναι σε κατάσταση // όπου με βεβαιότητα δεν ανιχνεύει κίνηση. 'Αρα η τιμή HIGH που // μόλις διαβάστηκε, σημαίνει ότι αυτή τη στιγμή ο PIR ανιχνεύει // νέα κίνηση. Serial.println("---"); Serial.print("motion detected at "); Serial.print(millis() / 1000); Serial.println(" sec"); // ΕΔΩ ΘΑ ΑΝΑΒΕΙ ΤΟ ΦΩΣ ΤΟΥ ΣΥΝΑΓΕΡΜΟΥ // Η μεταβλητή lockLow γίνεται false για να δείχνει ότι στο εξής // θεωρούμε ότι συνεχίζεται η κίνηση που μόλις ανιχνεύθηκε. lockLow = false; delay(150); } // Κάνουμε true το takeLowTime ώστε να είναι δυνατή η καταγραφή // της επόμενης χρονικής στιγμής που ο PIR θα δώσει LOW takeLowTime = true; } // endif high if (digitalRead(pirPin) == LOW) { // Ο PIR έδωσε LOW είτε διότι σταμάτησε να υπάρχει κίνηση, είτε // διότι πρόκειται για στιγμιαία αλλαγή κατάστασης του PIR (χωρίς να // έχει σταματήσει η κίνηση στο χώρο). // Ανάβει το led 13 για να δείξει ότι ο PIR έδωσε LOW. digitalWrite(ledPin, LOW); if (takeLowTime) { // Το takeLowTime είναι true μόνο αν η προηγούμενη κατάσταση // του PIR έδινε HIGH, όταν δηλ. θέλουμε να καταγράψουμε τον χρόνο // που αρχίζει ο PIR να δίνει LOW. // Tώρα που δίνει LOW αποθηκεύεται η συγκεκριμένη χρονική στιγμή // στην μεταβλητή lowIn lowIn = millis(); // Κάνουμε το takeLowTime false, ώστε όσο ο PIR συνεχίζει να δίνει // LOW, να μην καταγραφεί πλέον άλλη χρονική στιγμή. Θέλουμε δηλ. // να αποθηκεύσουμε στην lowIn στην χρονική στιγμή όπου άρχισε ο // PIR να δίνει LOW. takeLowTime = false; } // Συγκρίνουμε την διαφορά μεταξύ της στιγμής που ο PIR άρχισε να δίνει // LOW (μεταβλητή lowIn) και της τρέχουσας χρονικής στιγμής (millis()). // Αν η διαφορά αυτή είναι μεγαλύτερη από 5 sec (μεταβλητή pause), τότε // θεωρούμε ότι το LOW που δίνει ο PIR οφείλεται πραγματικά στο // σταμάτημα της κίνησης και δεν είναι προσωρινή αλλαγή κατάστασης. if (!lockLow && millis() - lowIn > pause) { Serial.print("motion ended at "); Serial.print((millis() - pause) / 1000); Serial.println(" sec"); // Εδώ θα σβήνει το φως του συναγερμού // Κάνουμε το lockLow true, ώστε η επόμενη μετάβαση του PIR // σε κατάσταση HIGH να θεωρηθεί ότι είναι αρχή νέας κίνησης // που ανιχνεύθηκε. lockLow = true; delay(150); } } // endif low }