marabatzis Δημοσ. 23 Οκτωβρίου 2015 Δημοσ. 23 Οκτωβρίου 2015 Σχεδιάζω την κατασκευή του ηλεκτρονικού μέρους μιας τηλεχειριζόμενης διπλής ανοιγόμενης αυλόπορτας. Χρησιμοποιώ 3 ρελέ που προσπαθώ να τα χειριστώ με το arduino, το 1ο καθορίζει την πολικότητα του ρεύματος των μοτέρ των μηχανισμών, και τα άλλα δύο, ένα για κάθε μοτέρ πόρτας. Για να σας προλάβω δεν είναι πτυχιακή, ούτε φτιάχνω κάτι για να το πουλήσω, άλλωστε δημοσιεύω εδώ όλη τη διαδικασία της κατασκευής (θα ακολουθήσει και το σχέδιο, και φωτογραφίες), ώστε να μπορεί όποιος θέλει να κατασκευάσει τον αυτοματισμό. Η ιδέα μου ήρθε ένας τέτοιος αυτοματισμός της αυλόπορτας φίλου χάλασε και μου ζήτησε τη βοήθειά μου. Προσπάθησα αλλά δεν μπόρεσα να τον επισκευάσω, οπότε ψάχνοντας για λύση σκέφτηκα... Τέτοιος αυτοματισμός πουλιέται στην αγορά, κοστίζει περισσότερα από 100 Ε και χρειάζεται πάρα πολύς προγραμματισμός για να στηθεί και να παίξει τελικά. Με ένα nano arduino 3Ε και με υλικά από την κατεστραμμένη πλακέτα (ρελέ κ.α.), ο τηλεχειρισμός ήταν εξωτερικός (αλλά από ότι διάβασα σε άλλο άρθρο υπάρχει διαθέσιμος δέκτης 433ΜΗz για το arduino πάμφθηνος). Παρακάτω είναι το πρόγραμμα... Το πρόβλημά μου είναι ότι δεν γνωρίζω ακόμη (διαβάζω και προσπαθώ να βρω λύση) πως να χρησιμοποιήσω την milis και να αντικαταστήσω τα delay. /*Έλεγχος διπλής Ανοιγόμενης Πόρτας Ρελέ 1 = (καθορίζει την πολικότητα της τάσης στα μοτέρ = σε κατάσταση OFF οι πόρτες κλείνουν/σε κατάσταση OΝ οι πόρτες ανοίγουν. Ρελέ 2 = καθορίζει αν στο μοτέρ της 1ης πόρτας θα πηγαίνει τάση Ρελέ 3 = καθορίζει αν στο μοτέρ της 2ης πόρτας θα πηγαίνει τάση buttonPin = Είσοδος του μοναδικού μπουτόν, currentreader1 = αισθητήρας ρεύματος μοτέρ 1ης πόρτας currentreader2 = αισθητήρας ρεύματος μοτέρ 2ης πόρτας Λειτουργία αναλυτικά: Αρχική Κατάσταση με τις πόρτες κλειστές και τα ρελέ σε θέση OFF. 1ο πάτημα μπουτόν = η πρώτη πόρτα αρχίζει να ανοίγει. = μετά απο 2sec αρχίζει να ανοίγει και η δεύτερη πόρτα. currentReader 1 & 2 = οποιοδήποτε απο τα δύο αναλλογικά σήματα δείξουν ότι το ρεύμα ξεπέρασε το όριο οι πόρτες σταματούν να ανοίγουν και το σύστημα επανέρχεται στην Αρχική Κατάσταση( οι πόρτες θεωρούνται κλειστές). 2ο πάτημα μπουτόν = αν πραγματοποιηθεί ενώ δεν έχουν ανοίξει πλήρως οι πόρτες, το άνοιγμα σταματά και το σύστημα επανέρχεται στην Αρχική Κατάσταση Μετά απο χρόνο 20 sec το σύστημα επανέρχεται στην Τελική Κατάσταση (οι πόρτες θεωρούνται ανοιχτές). Τελική Κατάσταση με τις πόρτες ανοιχτές και τα ρελέ στη θέση OFF. 2ο πάτημα μπουτόν = αν πραγματοποιηθεί αφού έχουν ανοίξει πλήρως, οι πόρτες αρχίζουν να κλείνουν 3ο πάτημα μπουτόν = αν πραγματοποιηθεί ενώ οι πόρτες δεν έχουν κλείσει, τό κλείσιμο σταματά το σύστημα επανέρχεται στην Tελική Κατάσταση currentReader 1 & 2 = οποιοδήποτε απο τα δύο αναλλογικά σήματα δείξουν ότι το ρεύμα ξεπέρασε το όριο οι πόρτες σταματούν να κλείνουν και το σύστημα επανέρχεται στην Τελική Κατάσταση. Μετά απο χρόνο 20 sec το σύστημα επανέρχεται στην Αρχική Κατάσταση (οι πόρτες θεωρούνται Κλειστές). */ int switchPin = 2; // switch is connected to pin 2 int relay1Pin = 8; int relay2Pin = 9; int relay3Pin = 10; int val; // variable for reading the pin status int val2; // variable for reading the delayed status int buttonState; // variable to hold the button state int Mode = 0; // What mode is the light in? void setup() { pinMode(switchPin, INPUT); // Set the switch pin as input pinMode(relay1Pin, OUTPUT); pinMode(relay2Pin, OUTPUT); pinMode(relay13in, OUTPUT); buttonState = digitalRead(switchPin); // read the initial state } void loop(){ val = digitalRead(switchPin); // read input value and store it in val delay(10); // 10 milliseconds is a good amount of time val2 = digitalRead(switchPin); // read the input again to check for bounces if (val == val2) { // make sure we got 2 consistant readings! if (val != buttonState) { // the button state has changed! if (val == LOW) { // check if the button is pressed if (Mode == 0) { Mode = 1; } else { if (Mode == 1) { Mode = 2; } else { if (Mode == 2) { Mode = 3; } else { if (Mode == 3) { Mode = 0; } } } } } } buttonState = val; // save the new state in our variable } // Now do whatever the lightMode indicates if (Mode == 3) { // stop-door digitalWrite(relay1Pin, LOW); digitalWrite(relay2Pin, LOW); digitalWrite(relay3Pin, LOW); } if (Mode == 0) { //opening-door digitalWrite(relay1Pin, HIGH); digitalWrite(relay2Pin, HIGH); delay(1500); // αυτή η καθυστέρηση να γίνει χωρίς delay digitalWrite(relay3Pin, HIGH); delay(10000);// αυτή η καθυστέρηση να γίνει χωρίς delay digitalWrite(relay1Pin, LOW); digitalWrite(relay2Pin, LOW); digitalWrite(relay3Pin, LOW); Mode = 1; } if (Mode == 1) { //stop-door digitalWrite(relay1Pin, LOW); digitalWrite(relay2Pin, LOW); digitalWrite(relay3Pin, LOW); } if (Mode == 2) { //closing-door digitalWrite(relay1Pin, LOW); digitalWrite(relay3Pin, HIGH); delay(1500);// αυτή η καθυστέρηση να γίνει χωρίς delay digitalWrite(relay2Pin, HIGH); delay(10000);// αυτή η καθυστέρηση να γίνει χωρίς delay digitalWrite(relay1Pin, LOW); digitalWrite(relay2Pin, LOW); digitalWrite(relay3Pin, LOW); Mode = 3; } } Ευχαριστώ εκ των προτέρων, για οποιαδήποτε σκέψη και παρατήρηση. 2
CtrlFreak Δημοσ. 23 Οκτωβρίου 2015 Δημοσ. 23 Οκτωβρίου 2015 1) Βάλε τον κώδικα σε code tags 2) Λες "πως να χρησιμοποιήσω την milis και να αντικαταστήσω τα delay. " τι εννοείς? 3) if (val == val2) { // make sure we got 2 consistant readings! if (val != buttonState) { // the button state has changed! if (val == LOW) { μπορούν να γίνουν if (val == val2 & val != buttonstate & val == low) 4) delay(10000);// αυτή η καθυστέρηση να γίνει χωρίς delay τι εννοείς? 5) Το delay για την επιβεβαίωση βάλτο πιο μεγάλο 50 ms πχ
marabatzis Δημοσ. 23 Οκτωβρίου 2015 Μέλος Δημοσ. 23 Οκτωβρίου 2015 Ευχαριστώ για τις πρώτες συμβουλές, έκανα την αλλαγή που προτείνεις. Λοιπόν χρειάζομαι δύο χρόνους(time) 1ος 2sec(στο πρόγραμμα είναι delay(1500),έπρεπε να είναι (2000) 2ος 20sec((στο πρόγραμμα είναι delay(10000),έπρεπε να είναι (20000) ίσως οι διαφορές να σε μπέρδεψαν. 1ο πάτημα μπουτόν = η πρώτη πόρτα αρχίζει να ανοίγει. = μετά απο 2sec αρχίζει να ανοίγει και η δεύτερη πόρτα. (δεν μπορεί να ξεκινήσει πρώτα η δεύτερη πόρτα γιατί θα παρασύρει και την πρώτη). όταν οι πόρτες αρχίσουν να κλείνουν, πρέπει να ξεκινήσει πρώτα η δεύτερη και μετά από 2sec η πρώτη (αν ξεκινήσει πρώτα η πρώτη, η δεύτερη θα πέσει πάνω στην πρώτη και δεν θα κλείσει-Θα τα δείξω και τα δύο και με σχέδιο). Και τα 20 sec υπολογίζω ότι είναι ο χρόνος που απαιτείται είτε για να ανοίξουν τελείως οι πόρτες, είτε για να κλείσουν. Αν την καθυστέρηση αυτή την κάνω με την εντολή delay() τότε αν κατά τη διάρκεια του ανοίγματος ή του κλεισίματος πατηθεί το μπουτόν, αυτό δεν θα το καταλαβαίνει το arduino. Πρέπει να προσθέσω και έναν αισθητήρα ρεύματος, αν βρεθεί κάποιο εμπόδιο κατά τη διάρκεια του ανοίγματος ή του κλεισίματος πρέπει το σύστημα να ακινητοποιείται, με την εντολή delay() δεν μπορεί να γίνει κάτι τέτοιο. Χρειάζεται ένας μετρητής χρόνου, κάτι σαν το unsigned long previousMillis = 0; // will store last time LED was updated // constants won't change : const long interval1 = 2000; // interval1 at which to LED-LOW (milliseconds) const long interval2 = 20000; // if the LED is off turn it on and vice-versa: if (Mode == 0) { //opening-door digitalWrite(led1Pin, HIGH);digitalWrite(led2Pin, HIGH); if(currentMillis - previousMillis >= interval1) { // save the last time you blinked the LED previousMillis = currentMillis; digitalWrite(led3Pin, HIGH); όμως κάπου κάνω λάθος. Το πρόγραμμα με τις αλλαγές... /*Έλεγχος διπλής Ανοιγόμενης Πόρτας Ρελέ 1 = (καθορίζει την πολικότητα της τάσης στα μοτέρ = σε κατάσταση OFF οι πόρτες κλείνουν/σε κατάσταση OΝ οι πόρτες ανοίγουν. Ρελέ 2 = καθορίζει αν στο μοτέρ της 1ης πόρτας θα πηγαίνει τάση Ρελέ 3 = καθορίζει αν στο μοτέρ της 2ης πόρτας θα πηγαίνει τάση buttonPin = Είσοδος του μοναδικού μπουτόν, currentreader1 = αισθητήρας ρεύματος μοτέρ 1ης πόρτας currentreader2 = αισθητήρας ρεύματος μοτέρ 2ης πόρτας Λειτουργία αναλυτικά: Αρχική Κατάσταση με τις πόρτες κλειστές και τα ρελέ σε θέση OFF. 1ο πάτημα μπουτόν = η πρώτη πόρτα αρχίζει να ανοίγει. = μετά απο 2sec αρχίζει να ανοίγει και η δεύτερη πόρτα. currentReader 1 & 2 = οποιοδήποτε απο τα δύο αναλλογικά σήματα δείξουν ότι το ρεύμα ξεπέρασε το όριο οι πόρτες σταματούν να ανοίγουν και το σύστημα επανέρχεται στην Αρχική Κατάσταση( οι πόρτες θεωρούνται κλειστές). 2ο πάτημα μπουτόν = αν πραγματοποιηθεί ενώ δεν έχουν ανοίξει πλήρως οι πόρτες, το άνοιγμα σταματά και το σύστημα επανέρχεται στην Αρχική Κατάσταση Μετά απο χρόνο 20 sec το σύστημα επανέρχεται στην Τελική Κατάσταση (οι πόρτες θεωρούνται ανοιχτές). Τελική Κατάσταση με τις πόρτες ανοιχτές και τα ρελέ στη θέση OFF. 2ο πάτημα μπουτόν = αν πραγματοποιηθεί αφού έχουν ανοίξει πλήρως, οι πόρτες αρχίζουν να κλείνουν 3ο πάτημα μπουτόν = αν πραγματοποιηθεί ενώ οι πόρτες δεν έχουν κλείσει, τό κλείσιμο σταματά το σύστημα επανέρχεται στην Tελική Κατάσταση currentReader 1 & 2 = οποιοδήποτε απο τα δύο αναλλογικά σήματα δείξουν ότι το ρεύμα ξεπέρασε το όριο οι πόρτες σταματούν να κλείνουν και το σύστημα επανέρχεται στην Τελική Κατάσταση. Μετά απο χρόνο 20 sec το σύστημα επανέρχεται στην Αρχική Κατάσταση (οι πόρτες θεωρούνται Κλειστές). */ int switchPin = 2; // switch is connected to pin 2 int led1Pin = 8; int led2Pin = 9; int led3Pin = 10; int val; // variable for reading the pin status int val2; // variable for reading the delayed status int buttonState; // variable to hold the button state int Mode = 0; // What mode is the light in? void setup() { pinMode(switchPin, INPUT); // Set the switch pin as input pinMode(led1Pin, OUTPUT); pinMode(led2Pin, OUTPUT); pinMode(led3Pin, OUTPUT); buttonState = digitalRead(switchPin); // read the initial state } void loop(){ val = digitalRead(switchPin); // read input value and store it in val delay(50); // 10 milliseconds is a good amount of time val2 = digitalRead(switchPin); // read the input again to check for bounces if (val == val2 & val != buttonState & val == LOW) // make sure we got 2 consistant readings! // the button state has changed! // check if the button is pressed if (Mode == 0) { Mode = 1; } else { if (Mode == 1) { Mode = 2; } else { if (Mode == 2) { Mode = 3; } else { if (Mode == 3) { Mode = 0; } } } } } } buttonState = val; // save the new state in our variable } // Now do whatever the lightMode indicates if (Mode == 3) { // stop-door digitalWrite(led1Pin, LOW); digitalWrite(led2Pin, LOW); digitalWrite(led3Pin, LOW); } if (Mode == 0) { //opening-door digitalWrite(led1Pin, HIGH); digitalWrite(led2Pin, HIGH); delay(2000); // αυτή η καθυστέρηση να γίνει χωρίς delay digitalWrite(led3Pin, HIGH); delay(20000);// αυτή η καθυστέρηση να γίνει χωρίς delay digitalWrite(led1Pin, LOW); digitalWrite(led2Pin, LOW); digitalWrite(led3Pin, LOW); Mode = 1; } if (Mode == 1) { //stop-door digitalWrite(led1Pin, LOW); digitalWrite(led2Pin, LOW); digitalWrite(led3Pin, LOW); } if (Mode == 2) { //closing-door digitalWrite(led1Pin, LOW); digitalWrite(led3Pin, HIGH); delay(2000);// αυτή η καθυστέρηση να γίνει χωρίς delay digitalWrite(led2Pin, HIGH); delay(20000);// αυτή η καθυστέρηση να γίνει χωρίς delay digitalWrite(led1Pin, LOW); digitalWrite(led3Pin, LOW); digitalWrite(led2Pin, LOW); Mode = 3; } } Αυτό if (val == val2 & val != buttonstate & val == low) δεν δούλεψε, δεν πειράζει, ας το αφήσουμε όπως το βρήκα.
CtrlFreak Δημοσ. 24 Οκτωβρίου 2015 Δημοσ. 24 Οκτωβρίου 2015 Αντί του & δοκίμασε το AND. Επίσης αν δεν θέλεις delay που θα παγώνει το πρόγραμμα και δεν θα μπορείς κατά την διάρκεια να διαβάζεις εισόδους δοκίμασε interrupt ή απλά κάποια επαφή που θα σου δίνει το ΟΚ (θα διαβάζεις τάση) ότι η πόρτα έχει φτάσει στο μέγιστο άνοιγμα. Ή με το διάβασμα του ρεύματος, το "ζόρισμα" των μοτερ θα σου δίνει το ΟΚ ότι έφτασε στο μέγιστο ή βρήκε εμπόδιο. Καλύτερα με το ρεύμα πάντως. Και φτιάξε λίγο τον κώδικα φαίνεται να υπάρχουν παραπάνω αγκύλες
groot Δημοσ. 24 Οκτωβρίου 2015 Δημοσ. 24 Οκτωβρίου 2015 Αδερφέ!Η millis δείχνει πόση ώρα έχει περάσει από την στιγμή που έχει πάρει μπρος το arduino. Είναι κάτι που θες αυτό; Δηλαδή, θες κάποιον "απόλυτο" χρόνο ή μια σχετική καθυστέρηση;Επίσης, επειδή είναι ωραίο αυτό που φτιάχνεις, προτείνω (εάν συμφωνείς και εσύ) να ξεχάσεις λίγο τον κώδικα και να ανεβάσεις ένα διάγραμμα ροής με το τι θες να γίνεται.Εγώ, τουλάχιστον, προτίθεμαι μα βοηθήσω αλλά να κάτσω να διαβάσω κώδικα και λογική που θες να γίνεται και να το κάνουμε να παίξει, λίγο δύσκολο. Εάν δεν ψηθείς για το διάγραμμα, όλο και κάτι θα γίνει. Αλλά σίγουρα θα πάρεις παραπάνω βοήθεια με το διάγραμμα. Και εσύ και όποιος άλλος ασχοληθεί.Επίσης, το λογικό ΚΑΙ είναι &&. Το σκέτο & είναι bitwise Τώρα που ξαναείδα λίγο τον κώδικά σου... Προτείνω να διαχωρίσεις την λογική από τις διεργασίες με functions. Δηλαδή, έχεις μία λογική (την ροή) και κάτι που γίνεται. Αυτό που γίνεται (π.χ. άνοιξε πόρτα) βάλε το σε function. Την λογική άσε την στην "main" του sketch σου. Με την millis θα είσαι ΟΚ ΕΑΝ φροντίσεις και το θεματάκι που έχει. Δηλαδή, μετά από 50 ημέρες τρώει overflow και γυρνάει "λάθος" νούμερο. Π.χ., θα μπορούσες να έχεις μία function bool havePassedThatMuchTime(unsigned long previousTime /* In milliseconds */, unsigned int secondsToCheck /* In seconds */) { currentTime = millis(); if (currentTime < previousTime) { //Overflow, treat overflow } unsinged long timePassed = currentTime - previousTime; if ( (timePassed/1000) >= secondsToCheck ) return true; else return false; } και αυτή την function την καλείς όποτε θες να δεις για μία συγκεκριμένη χρονική στιγμή εάν έχουν περάσει τα δευτερόλεπτα που θες (ίσως η function έχει bug.. δες το).
παπι Δημοσ. 24 Οκτωβρίου 2015 Δημοσ. 24 Οκτωβρίου 2015 Δεν θες χρόνους. Θες state του project. Είναι ανοικτή η πόρτα Α/Β ; Μπορεί να ανοίξει η πορτ Α/Β; Μπορεί να κλεισει η πόρτα Α/Β; Έχει εμπόδια η πόρτα Α/Β; Κλπ Αν τα έχεις όλα αυτά, δεν θα χρειαστείς ούτε καν mc αλλά μόνο μερικούς τρανζίστορ και αντιστάσεις. Βέβαια καλύτερα ένα μc επειδή είναι πιο φτηνό από το να φτιαξεις πλακέτα.
marabatzis Δημοσ. 25 Οκτωβρίου 2015 Μέλος Δημοσ. 25 Οκτωβρίου 2015 Ευχαριστώ για τις απαντήσεις και τις προτάσεις σας. Συγνώμη που δεν απάντησα νωρίτερα (αλλά χθες δεν ήταν δυνατόν) Αυτό που χρειάζομαι είναι έναν μετρητή χρόνου να ξεκινάει το μέτρημα των δευτερολέπτων από τη στιγμή που θα πατηθεί το μπουτόν, ταυτόχρονα θα ξεκινήσει η πρώτη πόρτα να ανοίγει αν οι πόρτες είναι κλειστές, ή να κλείνει η δεύτερη πόρτα αν αυτές είναι ανοιχτές. Θέλω σε χρόνο t1 (π.χ.2sec) να ξεκινάει και η άλλη πόρτα, και σε χρόνο t2 (π.χ. 20sec) να απενεργοποιούνται τα ρελέ (όταν θα έχει ολοκληρωθεί ο κύκλος ανοίγματος ή κλεισίματος των πορτών). if (Mode == 0) { //opening-door digitalWrite(led1Pin, HIGH); digitalWrite(led2Pin, HIGH); delay(2000); // αυτή η καθυστέρηση να γίνει χωρίς delay digitalWrite(led3Pin, HIGH); delay(20000);// αυτή η καθυστέρηση να γίνει χωρίς delay digitalWrite(led1Pin, LOW); digitalWrite(led2Pin, LOW); digitalWrite(led3Pin, LOW); Mode = 1; } Όπως έχω φτιάξει ως τώρα το πρόγραμμα, αυτό γίνεται με το delay. Όμως αν πατηθεί το μπουτόν για να σταματήσει το άνοιγμα ή το κλείσιμο, στη μέση της διαδρομής για παράδειγμα,επειδή υπάρχει κάποιο εμπόδιο ή αν προσθέσω την παράμετρο ελέγχου του ρεύματος, αυτά, αφού γίνεται delay δεν λειτουργούν. Πρέπει να κάνω κάτι,τέτοιο, νομίζω, αλλά δεν είμαι καθόλου σχετικός και το κομμάτι που ακολουθεί έχει λάθη... unsigned long previousMillis = 0; // will store last time LED was updated // constants won't change : const long interval1 = 2000; // interval1 at which to LED-LOW (milliseconds) const long interval2 = 20000; // if the LED is off turn it on and vice-versa: if (Mode == 0) { //opening-door digitalWrite(led1Pin, HIGH); digitalWrite(led2Pin, HIGH); if(currentMillis - previousMillis >= interval1) { // save the last time you blinked the LED previousMillis = currentMillis; digitalWrite(led3Pin, HIGH); Θα μπορούσα να τα φτιάξω με flip-flop και με το 555, αλλά νομίζω πως θα κοστίσουν περισσότερο από τα Ευρώ του nano... Άλλωστε το πρόγραμμα μπορεί να βελτιωθεί, και να επανεγκατασταθεί, ενώ θα αρχίσει να λειτουργεί. CtrlFreak δεν διάβασα προσεκτικά το μήνυμά σου. Οι μηχανισμοί με τα μοτέρ έχουν ενσωματωμένους τερματικούς διακόπτες και στις δύο κατευθύνσεις εμείς δίνουμε ρεύμα και αυτοί λειτουργούν, το σημείο τερματισμού ρυθμίζεται με κατσαβίδι, δεν χρειάζεται κάτι άλλο.
CtrlFreak Δημοσ. 26 Οκτωβρίου 2015 Δημοσ. 26 Οκτωβρίου 2015 CtrlFreak δεν διάβασα προσεκτικά το μήνυμά σου. Οι μηχανισμοί με τα μοτέρ έχουν ενσωματωμένους τερματικούς διακόπτες και στις δύο κατευθύνσεις εμείς δίνουμε ρεύμα και αυτοί λειτουργούν, το σημείο τερματισμού ρυθμίζεται με κατσαβίδι, δεν χρειάζεται κάτι άλλο. Άρα οι διακόπτες θα σου δώσουν το ΟΚ ότι η πόρτα έκλεισε? Όσο για το delay μόνο με interrupt.
groot Δημοσ. 26 Οκτωβρίου 2015 Δημοσ. 26 Οκτωβρίου 2015 @marabatzis Με αυτό που είπε ο παπί και αυτό που σου έγραψα εγώ, γίνεται δουλειά. Επιλέγεις να μην το διαβάσεις ή να μην ασχοληθείς... good luck!
nkarama Δημοσ. 26 Οκτωβρίου 2015 Δημοσ. 26 Οκτωβρίου 2015 Ερώτηση 1: Φαντάζομαι ότι το delay δεν το θες γιατί μπλοκάρει την εκτέλεση του προγράμματος εκει, περιμένοντας να ολοκληρωθεί ο χρόνος για να εκτελέσει την επόμενη εντολή, σωστά? Ερώτηση 2: Αν κατάλαβα καλά, την ώρα που ανοίγουν 'η κλείνουν οι πόρτες (ακι στο συγκεκριμένο πρόγραμμα εκτελείτε η delay) εσύ θες να μπορείς να ανιχνεύσεις εντολές απο το τηλεκοντρόλ ή απο τον αισθητήρα ρεύματος, σωστά? Αν ναι, τότε διάβασε καλύτερα τι σου είπε το παπί ποιο πάνω... Φτιάξε το state machine σου και καθόρισε τις συνθήκες με τις οποίες θα κινήσε στο καθένα. Μην ξεχνάς ότι όλα αυτά γίνονται μέσα σε ένα loop που εκτελείτε συνέχεια. Η αντικατάσταση της Delay γίνετε με το να αποθηκευσεις την τιμή του millis() σε μια unsigned long μεταβλητή και μετά να ελέγξεις τον χρόνο που πέρασε πχ unsigned int interval = 2000; unsigned long startTime= millis(); . . . . if (millis() - startTime >= interval) { // Do stuff } Προσοχή στην συνθήκη. Λόγω του ότι το millis() κάνει overflow κάθε περίπου 49 μέρες, η συνθήκη για τον έλεγχο πρέπει να είναι σε αυτή την μορφή (με αφαίρεση), διαφορετικά η συμπεριφορά του προγράμματος θα είναι απρόβλεπτη. Edit: και αφού δεν έχω δουλειά, ας πούμε λίγα παραπάνω: Σκέψου το εξής state machine (χωρίς σε καμμιά περίπτωση να είναι όλοκληρωμένο) void loop() { if (state == doorClosed) { previousState = doorClosed; relay1 = somevalue; relay2 = somevalue; relay3 = somevalue; if (button == pressed) { //Light some leds, sound a beep state = doorsOpening; } if (state == doorsOpening) { if (previousState != doorsOpening) { startOpeningDoors = now() previousState = doorsOpening; } relay1 = somevalue; relay2 = somevalue; if (millis() - startOpeningDoors >= 2000) { relay3 = somevalue; } if (button == pressed) { state = doorsStoped; } if (currentSesnor = trggered) { state = currectToHigh; } if (millis() - startOpeningDoors >= 20000) { state = DoorsStoped; } } if (state = doorsStoped) { //set relay values; //Check for other applicable keypreses on that state //set state according to key preses } if (state = currentToHigh) { //Do stuff } } } //Loop end. Καλό είναι να ξέρεις την προηγούμενη κατάσταση για να μπορείς να κάνεις κάποιος ελέγχους στο σύστημά σου. Ενδεικτικά την έβαλα σαν πρώτη εντολή μέσα σε κάθε if. Αλπίζω να το έπιασες το concept τώρα...
groot Δημοσ. 26 Οκτωβρίου 2015 Δημοσ. 26 Οκτωβρίου 2015 Αδερφέ! Η millis δείχνει πόση ώρα έχει περάσει από την στιγμή που έχει πάρει μπρος το arduino. Είναι κάτι που θες αυτό; Δηλαδή, θες κάποιον "απόλυτο" χρόνο ή μια σχετική καθυστέρηση; Επίσης, επειδή είναι ωραίο αυτό που φτιάχνεις, προτείνω (εάν συμφωνείς και εσύ) να ξεχάσεις λίγο τον κώδικα και να ανεβάσεις ένα διάγραμμα ροής με το τι θες να γίνεται. Εγώ, τουλάχιστον, προτίθεμαι μα βοηθήσω αλλά να κάτσω να διαβάσω κώδικα και λογική που θες να γίνεται και να το κάνουμε να παίξει, λίγο δύσκολο. Εάν δεν ψηθείς για το διάγραμμα, όλο και κάτι θα γίνει. Αλλά σίγουρα θα πάρεις παραπάνω βοήθεια με το διάγραμμα. Και εσύ και όποιος άλλος ασχοληθεί. Επίσης, το λογικό ΚΑΙ είναι &&. Το σκέτο & είναι bitwise Τώρα που ξαναείδα λίγο τον κώδικά σου... Προτείνω να διαχωρίσεις την λογική από τις διεργασίες με functions. Δηλαδή, έχεις μία λογική (την ροή) και κάτι που γίνεται. Αυτό που γίνεται (π.χ. άνοιξε πόρτα) βάλε το σε function. Την λογική άσε την στην "main" του sketch σου. Με την millis θα είσαι ΟΚ ΕΑΝ φροντίσεις και το θεματάκι που έχει. Δηλαδή, μετά από 50 ημέρες τρώει overflow και γυρνάει "λάθος" νούμερο. Π.χ., θα μπορούσες να έχεις μία function bool havePassedThatMuchTime(unsigned long previousTime /* In milliseconds */, unsigned int secondsToCheck /* In seconds */) { currentTime = millis(); if (currentTime < previousTime) { //Overflow, treat overflow } unsinged long timePassed = currentTime - previousTime; if ( (timePassed/1000) >= secondsToCheck ) return true; else return false; } και αυτή την function την καλείς όποτε θες να δεις για μία συγκεκριμένη χρονική στιγμή εάν έχουν περάσει τα δευτερόλεπτα που θες (ίσως η function έχει bug.. δες το). Ερώτηση 1: Φαντάζομαι ότι το delay δεν το θες γιατί μπλοκάρει την εκτέλεση του προγράμματος εκει, περιμένοντας να ολοκληρωθεί ο χρόνος για να εκτελέσει την επόμενη εντολή, σωστά? Ερώτηση 2: Αν κατάλαβα καλά, την ώρα που ανοίγουν 'η κλείνουν οι πόρτες (ακι στο συγκεκριμένο πρόγραμμα εκτελείτε η delay) εσύ θες να μπορείς να ανιχνεύσεις εντολές απο το τηλεκοντρόλ ή απο τον αισθητήρα ρεύματος, σωστά? Αν ναι, τότε διάβασε καλύτερα τι σου είπε το παπί ποιο πάνω... Φτιάξε το state machine σου και καθόρισε τις συνθήκες με τις οποίες θα κινήσε στο καθένα. Μην ξεχνάς ότι όλα αυτά γίνονται μέσα σε ένα loop που εκτελείτε συνέχεια. Η αντικατάσταση της Delay γίνετε με το να αποθηκευσεις την τιμή του millis() σε μια unsigned long μεταβλητή και μετά να ελέγξεις τον χρόνο που πέρασε πχ unsigned int interval = 2000; unsigned long startTime= millis(); . . . . if (millis() - startTime >= interval) { // Do stuff } Προσοχή στην συνθήκη. Λόγω του ότι το millis() κάνει overflow κάθε περίπου 49 μέρες, η συνθήκη για τον έλεγχο πρέπει να είναι σε αυτή την μορφή (με αφαίρεση), διαφορετικά η συμπεριφορά του προγράμματος θα είναι απρόβλεπτη. Edit: και αφού δεν έχω δουλειά, ας πούμε λίγα παραπάνω: Σκέψου το εξής state machine (χωρίς σε καμμιά περίπτωση να είναι όλοκληρωμένο) void loop() { if (state == doorClosed) { previousState = doorClosed; relay1 = somevalue; relay2 = somevalue; relay3 = somevalue; if (button == pressed) { //Light some leds, sound a beep state = doorsOpening; } if (state == doorsOpening) { if (previousState != doorsOpening) { startOpeningDoors = now() previousState = doorsOpening; } relay1 = somevalue; relay2 = somevalue; if (millis() - startOpeningDoors >= 2000) { relay3 = somevalue; } if (button == pressed) { state = doorsStoped; } if (currentSesnor = trggered) { state = currectToHigh; } if (millis() - startOpeningDoors >= 20000) { state = DoorsStoped; } } if (state = doorsStoped) { //set relay values; //Check for other applicable keypreses on that state //set state according to key preses } if (state = currentToHigh) { //Do stuff } } } //Loop end. Καλό είναι να ξέρεις την προηγούμενη κατάσταση για να μπορείς να κάνεις κάποιος ελέγχους στο σύστημά σου. Ενδεικτικά την έβαλα σαν πρώτη εντολή μέσα σε κάθε if. Αλπίζω να το έπιασες το concept τώρα... Αδερφέ OP... τρίτωσε το κακό. Ξαναδιάβασε τα μηνύματα και εδώ είμαστε.
marabatzis Δημοσ. 26 Οκτωβρίου 2015 Μέλος Δημοσ. 26 Οκτωβρίου 2015 Αδερφέ OP... τρίτωσε το κακό. Ξαναδιάβασε τα μηνύματα και εδώ είμαστε. Ευχαριστώ για την προσπάθειά σας να με βοηθήσετε. Θα μελετήσω λίγο περισσότερο, είμαι ακόμη αρχάριος και κάποια πράγματα από αυτά που έγραψες ( ...να διαχωρίσεις την λογική από τις διεργασίες με functions....Την λογική άσε την στην "main" του sketch σου...) είναι ακόμη ακαταλαβίστικα. Αν μπορούσαν να γίνουν περισσότερο ελληνικά, αν έχεις χρόνο, εγώ έτσι κι αλλιώς εγώ στην προσπάθεια είμαι. Ένα απλός Ηλεκτρονικός είμαι, που προσπαθεί να ασχοληθεί με το arduino. Έως τώρα από προγραμματισμό μηδέν. Άλλος είναι OP! Συγνώμη τι είναι ΟΡ;
CtrlFreak Δημοσ. 26 Οκτωβρίου 2015 Δημοσ. 26 Οκτωβρίου 2015 original poster. Τεσπα κάνε ένα σχεδιάγραμμα του κυκλώματος και το διάγραμμα ροής του προγράμματος. 1
groot Δημοσ. 26 Οκτωβρίου 2015 Δημοσ. 26 Οκτωβρίου 2015 Ευχαριστώ για την προσπάθειά σας να με βοηθήσετε. Θα μελετήσω λίγο περισσότερο, είμαι ακόμη αρχάριος και κάποια πράγματα από αυτά που έγραψες ( ...να διαχωρίσεις την λογική από τις διεργασίες με functions....Την λογική άσε την στην "main" του sketch σου...) είναι ακόμη ακαταλαβίστικα. Αν μπορούσαν να γίνουν περισσότερο ελληνικά, αν έχεις χρόνο, εγώ έτσι κι αλλιώς εγώ στην προσπάθεια είμαι. Ένα απλός Ηλεκτρονικός είμαι, που προσπαθεί να ασχοληθεί με το arduino. Έως τώρα από προγραμματισμό μηδέν. Συγνώμη τι είναι ΟΡ; Good! Λοιπόν! functions = διεργασίες/λειτουργικότητες (ας πούμε). Δες το σαν ένα ωραίο τρόπο να "ομαδοποιείς" κώδικα. Αντί να έχεις ένα τεράστιο "κείμενο" ανάμεσα στα { } της loop, μαζεύεις τον κώδικα σε "ομάδες" και καλείς αυτές τις ομάδες όποτε χρειάζεται. Π.χ., εάν θέλεις να μετράς τον χρόνο που πέρασε: unsigned long theTime; void setup() { theTime = millis(); } void loop() { boolean hasTheTimePassed; hasTheTimePassed = havePassedThatMuchTime(theTime, 20); if (hasTheTimePassed) { // Do what ever has to be done } } bool havePassedThatMuchTime(unsigned long previousTime /* In milliseconds */, unsigned int secondsToCheck /* In seconds */) { currentTime = millis(); if (currentTime < previousTime) { //Overflow, treat overflow } unsinged long timePassed = currentTime - previousTime; if ( (timePassed/1000) >= secondsToCheck ) return true; else return false; } Το καλό (για εσένα και στην προκειμένη φάση) είναι ότι μπορείς να έχεις μαζεμένη και διαχωρισμένη την λειτουργικότητα (δηλαδή, το τι γίνεται) από την λογική (δηλαδή, το πότε γίνεται). Το sketch είναι το αρχείο σου για το arduino. Εάν πας να κάνεις new file θα δεις ότι λέει "new sketch". Το sketch σου τώρα, είναι χωρισμένο σε 4 μεγάλα κομμάτια (κανονικά είναι 3, αλλά ως 4 θα το καταλάβεις πιο εύκολα). global variables declaration, αυτό είναι πάνω-πάνω, εκεί όπου δηλώνεις τις μεταβλητές σου setup function, η function setup loop function, η κύρια function του arduino. Αφού κληθεί η setup και γίνει το setup των μεταβλητών, καλείται η loop και τρέχει συνέχεια. Εάν έγραφες C, θα καταλάβαινες την "παρομοίωση" με την main. functions declaration, αυτό είναι μετά την loop όπου και εκεί γράφεις τις δικές σου functions (μπορείς να τις γράψεις και σε άλλο αρχείο, αλλά προς το παρόν δεν νομίζω να σε απασχολεί κάτι τέτοιο) Οπότε, η main του sketch σου είναι η loop... απλά δεν θυμόμουν το όνομά της... και τώρα για να το γράψω έκανα scroll up. 1
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα