capthookb Δημοσ. 24 Οκτωβρίου 2015 Δημοσ. 24 Οκτωβρίου 2015 Φτιάχνω έναν PID controller με ένα arduino uno για έλεγχο θερμοκρασίας. Χρησιμοποιώ σαν βάση το παράδειγμα της βιβιλιοθήκης που υπάρχει για pid εδώ: http://playground.arduino.cc/Code/PIDLibraryRelayOutputExample #include <PID_v1.h> #define RelayPin 6 //Define Variables we'll be connecting to double Setpoint, Input, Output; //Specify the links and initial tuning parameters PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT); int WindowSize = 5000; unsigned long windowStartTime; void setup() { windowStartTime = millis(); //initialize the variables we're linked to Setpoint = 100; //tell the PID to range between 0 and the full window size myPID.SetOutputLimits(0, WindowSize); //turn the PID on myPID.SetMode(AUTOMATIC); } void loop() { Input = analogRead(0); myPID.Compute(); /************************************************ * turn the output pin on/off based on pid output ************************************************/ unsigned long now = millis(); if(now - windowStartTime>WindowSize) { //time to shift the Relay Window windowStartTime += WindowSize; } if(Output > now - windowStartTime) digitalWrite(RelayPin,HIGH); else digitalWrite(RelayPin,LOW); } Σε κάθε loop, τρέχει η myPID.Compute() και το αποτέλεσμα του υπολογισμού αλλάζει τη μεταβλητή Output, η οποία κυμαίνεται από 0 έως WindowSize (5000). Για παράδειγμα, αν η μεταβλητή Output υπολογιστεί να είναι 2500 σημαίνει πως πρέπει να παίρνω τη μισή θερμαντική ικανότητα του συστήματος. Αν η ισχύς της αντίστασης είναι 1000watt θα πρέπει να δουλεύει στα 500watt. Αν Output=1000 τότε, θα πρέπει να παρέχεται θερμότητα στο σύστημα ισχύος 200watt κ.οκ. Όμως αν έχουμε σταθερή ισχύ, θα πρέπει να μεταβάλλουμε το χρόνο που δουλεύει η αντίσταση, ώστε να έχουμε το ίδιο αποτέλσμα. Για παράδειγμα, αν Output=2500, τότε η αντίσταση των 1000watt θα πρέπει να δουλεύει Χ δευτερόλεπτα και να σβήνει για Χ δευτερόλεπτα, σε ένα παράθυρο χρόνου 2Χ. Αυτό προσπαθεί να κάνει ο κώδικας, αλλά δεν ξέρω κατά πόσο είναι σωστός. Βασικά δεν καταλαβαίνω το λόγο σύγκρισης του Output>now-windowStartTime και γι'αυτό δεν μπορώ να εκτιμήσω αν δουλεύει σωστά. Ο λόγος που αμφισβητώ το αν δουλεύει σωστά είναι πως σε μικρές τιμές της μεταβλητής output, το ρελέ δε δουλεύει καθόλου για χρονικό διάστημα που ξεπερνά δυο και τρεις φορές το WindowSize (δηλαδή 15 δευτερόλεπτα).
Rayven Δημοσ. 26 Οκτωβρίου 2015 Δημοσ. 26 Οκτωβρίου 2015 ολο το κοματι μεσα στο loop ειναι για να κανει την PWM διαμορφωση ωστε με κατι που δουλευει με δυο καταστασεισ να παρεισ μια αναλογικη εξοδο, οσο γινεται. Αποριες δικες μου: 1. τι ακριβως θελεις να ελεγξεις? 2. δεν θα σε βολευε ενας πιο απλος ελεγχος? Αυτο που εχεις ειναι PID (δηλαδη 3 κερδη, αναλογικο, ολοκληρωτικο και διαφορικο) με ενσωματωμενο adaptive control αφου εσωτερικα η βιβλιοθηκη σου κανει και αναγνωρση του συστηματος. 3. το να μη δουλευει το ρελε για μεγαλα χρονικα διαστηματα σε χαμηλες τιμες δε μου ακουγεται περιεργο. Αν δε σου αρεσει μπορεις να παιξεις με την τιμη του windowsize. Για να πεις οτι δε δουλευει θα πρεπει το τελικο αποτελεσμα να μην ειναι σωστο. Απο τους χρονους on για να βγαλεις συμπερασμα πρεπει να κανεις τα μαθηματικα. 4. Εχεις βεβαιωθει οτι το arduino μπορει να οδηγησει ηλεκτρικα τα συγκεκριμενα ρελε? 5. Ως αναλογικη εισοδο τι του βαζεις?
capthookb Δημοσ. 26 Οκτωβρίου 2015 Μέλος Δημοσ. 26 Οκτωβρίου 2015 Ναι, κανονικά ο pid έλεγχος, ορίζει το εύρος λειτουργίας ενός αναλογικού ελέγχου από 0-100%. Για παράδειγμα ο έλεγχος της πεταλούδα του γκαζιού σε ένα αυτοκίνητο, ανάλογα με το δρόμο όταν έχει cruise control, ο έλεγχος μιας αναλογικής βαλβίδας ατμού σε έναν εναλλάκτη κτλ. 1)Εγώ έχω φτιάξει ένα μικρό θάλαμο θέρμανσης, σαν φούρνο, που θέλω να δουλεύει σε ορισμένες θερμοκρασίες με μέγιστη τους 100-102C. Το θερμαντικό στοιχείο μου είναι μια λάμπα πυρακτώσεως 70watt. 2)Η ακρίβεια της θερμοκρασίας δεν είναι κρίσιμη για κάτι, ωστόσο θέλω να εξοικοιωθώ με τον προγραμματισμό και τον έλεγχο της διεργασίας με τη βοηθεια του PID. 3)Δεν ξέρω κατά πόσο το windowsize θα αλλάξει και το κατά πόσο θα δουλεύει πάντοτε, έστω και για msec το ρελέ. Ο λόγος είναι πως δηλώνεται και στο obect του pid. Η όλη απορία μου ξεκίνησε από την σκέψη του οτι o pid ενδεχομένως να υπολογίζει λάθος τιμές. Όταν το output είναι μικρό, ο έλεγχος του pid, δίνει μια μικρή ποσότητα θερμότητας και περιμένει να δει το αποτέλεσμα στη μεταβλητή που προσπαθεί να εξισώσει με το setpoint. Αν όμως το ρελέ δε δουλεύει, αυτό εισάγει λάθος δεδομένα στον υπολογισμό και ενδεχομένως αυξάνεται το output κατά πολύ περισσότερο. Και το "πρόβλημα" δεν είναι ο πολύ μικρός χρόνος λειτουργίας του ρελέ. Θα έβλεπα δηλαδή να ανοιγοκλείνει πολύ γρήγορα. Αυτό δε γίνεται, γιατί ο έλεγχος του if απορρίπτει όλες τις μικρές τιμές του output. 4)Πολλές γνώσεις ηλεκτρονικών/ηλεκτρολογίας δεν έχω. Όμως φαίνεται να δουλεύει κανονικά. Δεν παίζει καποιο θέμα δηλαδή αδυναμίας. 5)Το input μου είναι η θερμοκρασία του θαλάμου. Χρησιμοποιώ ένα ds18b20 αισθητήρα. Βασικά πιο πολύ απορία για το πως δουλεύει ακριβώς ο κώδικας έχω. Πιθανά να μην υπάρχει πρόβλημα (μεγάλο). Χθες έπαιζα με τις σταθερές του pid και έβαζα διαφορα setpoints: Μπλε: Setpoint Πράσινο: Η μεταβλητή output υπολογισμένη σαν 0-100% του windowtime Mωβ: Input
Rayven Δημοσ. 26 Οκτωβρίου 2015 Δημοσ. 26 Οκτωβρίου 2015 (επεξεργασμένο) Ξεκιναω με τα γραφηματα. Μου φαινεται οτι λειτουργει σωστα αν κρινω απο την ααποκριση του συστηματος. Στην ουσια ειναι ενα προβλημα tracking (παρακολουθηση εισοδου απο την εξοδο). Πρεπει να λαβεις υποψη σου οτι το συστημα εχει χρονοκαθυστερηση αφου η αυξηση της ενεργειας που καταναλωνει η αντισταση δεν μεταφραζεται αμεσως σε αυξηση της θερμοκρασιας στο θαλαμο. Οσο για τον κωδικα, πρπει να θυμασε οτι τρεχει πολλες φορες πριν κλεισει ο βρογχος του ελεγχου (μετρηση -υπολογισμος-εξοδος). Οποτε μεσα στο loop του κωδικα οι συνθηκες εξασφαλιζουν οτι δεν αλλαξουν οι τιμες μεχρι να εφαρμοστει ο ελεγχος. Το προγραμμα δεν περιμενει οποτε με καποιον τροπο πρεπει να ξεχωρισει ποιες επαναληψεις ειναι χρησιμες και ποιες οχι. Το windowsize ειναι στην ουσια η μεγιστη χρονικη διαρκεια ενος παλμου. Αν ο χρονος εχει ξεπερασει το windowsize, το πρωτο if μηδενιζει το ποτε ξεκινα ο νεος παλμος. Το δευτερο if , αφου η μεγιστη τιμη του output ειναι το windowsize, δημιουργει το υπολοιπο του windowsize που ο παλμος ειναι off. Οταν ειναι true δημιουγει το On του παλμου, και για τον υπολοιπο χρονο (υπολοιπο windowsize) δημιουργει το off. Για το συγκεκριμενο προβλημα καταλαβαινεις και μονος σου οτι ο PID ειναι overkill. Για εκπαιδευτικη εφαρμογη ωστε να μαθεις τον PID δε θα το προτεινα μιας και ειναι εξαιρετικα αργο οπως ειπα πριν και δεν βλεπεις τα πλεονεκτηματα του. Κλασικο εκπαιδευτικο προβλημα ειναι το αναποδο εκρεμες ή η κυλιομενη σφαιρα πανω σε ραβδο. Εκει τα μεταβατικα φαινομενα, η ευσταθεια αλλα και το σφαλμα στο συνεχες ειναι σημαντικα και ευκολα ορατα. Με το συγκεκριμενο παραδειγμα μπλεκεις και στα χωραφια της αναγνωρισης συστηματος χωρις να το γνωριζεις. Το προγραμμα παρακολουθει την εισοδο και την εξοδο και προσεγγιζει το συστημα με το ισοδυναμο δευτερου βαθμου. Στη θεωρια αυτο εισαγει επιπλεον καθυστερηση στον ελεγχο. Αν θες να μαθεις τον PID κατα τη γνωμη μου ξεκινα απο την συναρτηση μεταφορας του στο πεδιο Laplace, μαθε τι κανει, ποιοτικα, καθενα απο τα 3 κερδη και στη συνεχεια μαθε χειροκινητους τροπους ευρεσης των κερδων (τα οποια μενουν σταθερα). Εδω αν καταλαβα καλα σε καθε βημα δεν ειναι σταθερα (πρπει να δω τον κωδικα της βιβλιοθηκης για να σου πω με σιγουρια) Οσο για τα ηλεκτρικα και τεχνικα χαρακτηριστικα, πρεπει να εχει εξασφαλισει οτι μπορουν να δουλεψουν ολα μαζι. Δηλαδη η ταση λειτουργιας του αισθητηρα ειναι 3.3V ή 5V ωστε να μπορει να τροφοδοτηθει απο το arduino. Αν οχι θελει προσαρμογη. Το ευρος θερμοκρασιας του ειναι αρκετο για το συγκεκριμενο προβλημα? Τα ρελε ποσο ρευμα θελουν για να κλεισουν τις επαφες τους? μπορει να βγαλει τοσα ampere η ψηφιακη εξοδος του arduino? Ποσο χρονο θελουν για να το κανουν? Ειναι αρκετα μικρος η οδηγουν το συστημα σε ασταθεια? και αλλα θεματα, παραδειγματα φερνω, καταλαβες τη γενικη ιδεα. Δεν ξερω τι γνωσεις εχεις η ποσο βαθια θελεις να μαθεις τον PID οποτε συγνωμη αν το παρακανα με τα θεωρητικα. Επεξ/σία 27 Οκτωβρίου 2015 από Rayven 1
capthookb Δημοσ. 27 Οκτωβρίου 2015 Μέλος Δημοσ. 27 Οκτωβρίου 2015 Η χρονοκαθυστέρηση δεν αποτελεί πρόβλημα για τον έλεγχο, παρ'όλο που είναι αρκετά μικρή λόγω των διαστάσεων του κουτιού (κυλυνδρικό κουτί ύψους 12cm και διαμέτρου 12cm). Ο αισθητήρας είναι 7cm μακριά και πάνω από τη λάμπα και η παραμικρή λειτουργία γίνεται αισθητή. Ωστόσο υπάρχουν και εφαρμογές του pid που η χρονοκαθυστέρηση είναι πολύ μεγαλύτερη. Οι σταθερές ορίζουν το πως θα ανταποκρίνεται σε αυτές. Μπορεί να είναι πολύ γρηγορος στην απόκρισή του, και να αρχίζει να ταλαντώνεται γύρω από το setpoint ή να είναι πολύ αργός και να αργεί να ισορροπήσει, κάτι που μπορεί να συμπεριλάβει τη χρονική καθυστέρηση του συστήματος. Οι Κp, Ki, Kd είναι σταθερές ανά loop, και ανά εκτέλεση του προγράμματος. Μόνο αν τις αλλάξω εγω χειροκίνητα, ή εφαρμόσω τη δέυτερη βιβλιοθηκη που σου έλεγα μπορούν να αλλάξουν. Δε νομίζω πως είναι overkill με την έννοια πως θα μου χρειαστεί για το επόμενο σύστημα που θέλω να ελέγξω. Ένα φούρνο ξήρανσης, που θα μετράω θερμοκρασία εισόδου, εξόδου καθώς και σχετική υγρασία, και θα ελέγχω θερμοκρασία, υγρασία και ροή αέρα. Ο έλεγχος PID χρησιμοποιείται ευρέως για τη ρύθμιση θερμοκρασιών σε πολλά συστήματα. Φυσικά αν η ρύθμιση γίνεται μέσω αναλογικής εξόδου ή κάποιου PWM νομίζω τα πράγματα είναι πιο άμεσα και εύκολα. Στη σχολή μου είχα ενα μάθημα ρύθμισης διεργασιών, αν και έχουν περάσει αρκετά χρόνια από τότε. Οπότε ένα θεωρητικό υπόβαθρο το έχω και μια σχετική εμπειρία από την προηγούμενη δουλειά. Τώρα περί ηλεκτρονικών, ο αισθητήρας είναι σίγουρο πως δουλεύει με 5V και μια αντίσταση που έχω κολλήσει στο μεταξύ της ψηφιακής εξόδου του αισθητήρα και του +5V. To ρεύμα που καταναλώνει σε κατάσταση sleep είναι 1μΑ. Σε κανονική λειτουργία δεν πρέπει να είναι μεγάλο. Επίσης το επάνω όριο θερμοκρασίας του είναι +125C, και τσέκαρα σε νερό που βράζει το καλιμπράρισμά του, καθώς και με νερό με πάγο για τους 0C. Το ρελέ, δουλεύει κι αυτό με +5V, GND και σήμα που φεύγει από την ψηφιακή έξοδο του arduino. Το ρεύμα δηλαδή που χρησιμοποιείται, απ'όσο έχω καταλάβει τροφοδοτείται από το +5V και όχι από την ψηφιακή έξοδο του arduino το οποιο νομίζω μπορεί να παρέχει μέχρι 200ma. Οπότε ρελέ και αισθητήρας νομίζω είναι πολύ πιο κάτω και από το μισό ρεύμα που μπορεί να δώσει το arduino. Επίσης η απόκριση είναι πολύ γρήγορη. Αρχικά το είχα συνδέσει στην έξοδο 2 του arduino και κάθε φορά που έκανα upload το πρόγραμμα του arduino από το pc, το ρελέ τρελαινόταν στο άνοιξε κλείσε. Σίγουρα δηλαδή μπορεί να δουλέψει για κάποια msec on/off Νομίζω από θέμα hardware δεν υπάρχει κάποιο πρόβλημα. Όλα είναι οκ! Σχετικά με τον έλεγχο του if, εδώ είναι ένα κομμάτι από τις τιμές των μεταβλητών που συγκρίνονται στο if, δηλαδή Output και now-windowStartTime. To WindowSize ειναι 4000. Ενώ η μεταβλητή Output δεν είναι μηδέν σε κάθε εκτέλεση του loop (ή σε κάθε γραμμή εκτύπωσης παρακάτω), το ρελέ δουλεύει μόνο 3 φορές για χρόνους από 67-833msec, 153-919msec και 238-1004msec. Και είναι προφανές πως για αρκετούς παλμούς, δεν ανοίγει καθόλου. To 1o If, σωστά μετατοπίζει κάθε φορά το χρόνο ώστε να γίνεται η σύγκριση ανά καθορισμένο χρονικό περιθώριο κάθε φορα(windowsize). To 2o δεν καταλαβαίνω αν λειτουργεί σωστά ή με ακρίβεια. 219.33 2535 212.21 3301 213.90 67 <---Ενεργοποίηση ρελέ 214.97 833 <---Τέλος λειτουργίας 216.04 1599 217.11 2365 218.18 3131 219.24 3897 220.31 663 221.38 1429 222.45 2194 223.52 2960 224.59 3726 225.66 492 226.73 1258 227.79 2024 228.86 2790 229.93 3557 231.00 323 232.07 1089 233.14 1855 234.21 2621 235.28 3387 236.34 153<---Ενεργοποίηση ρελέ 237.41 919<---Τέλος λειτουργίας 238.48 1685 239.55 2451 240.62 3217 241.69 3983 242.76 749 243.83 1515 244.89 2280 245.96 3046 247.03 3812 248.10 578 249.17 1344 250.24 2110 251.31 2876 252.38 3642 253.44 408 254.51 1174 255.58 1940 256.65 2706 257.72 3472 258.79 238<---Ενεργοποίηση ρελέ 259.86 1004<---Τέλος λειτουργίας 260.93 1770 Μη ζητάς συγγνώμη! Κάθε άλλο, παρά κουράζεις. Ευχαριστώ για τη συμμετοχή
Rayven Δημοσ. 27 Οκτωβρίου 2015 Δημοσ. 27 Οκτωβρίου 2015 (επεξεργασμένο) Ειδα πιο επισταμενα τις βιβλιοθηκες. Ναι στη βιβλιοθηκη που χρησιμοποιεις τα Κp, Ki, Kd ειναι σταθερα. Τα εχεις ομως οπως το παραδειγμα. Δεν σημαινει οτι ειναι τα καλυτερα για το δικο σου προβλημα. Πρεπει να υπολογισεις για το δικο σου συστημα. Αυτο το κανεις ειτε αν βγαλεις τη συναρτηση μεταφορας του συστηματος ειτε θα πας πειραματκα. Στο google θα βρεις απλες πειραματικες μεθοδους πχ ki=kd=0, αυξανεις kp μεχρι να εχεις ταλαντωση σε βηματικη εισοδο δηλαδη βρηκες Κ περιθωριου, βαζεις Kp=0.5*kπεριθωριου, ανεβαζεις Κi μεχρι το σφαλμα μονιμης καταστασης να ειναι αποδεκτο και μετα αυξανεις και kd ωστε να ρυμθισεις την ταχυτητα και να σβησεις την αποσβενουμενη ταλαντωση. Τα νουμερα που παραθετεις δε με βοηθανε γιατι δεν ξερω το input. Ακομα και να το ειχες βαλει παλι δε λεει πολλα γιατι δεν ειναι μια χρησιμη αποκριση πχ βηματικη αποκριση η κρουστικη αποκριση. Τα γραφηματα που εβαλες ειναι πιο χρησιμα. Ετσι οπως το βλεπω εμπειρικα μου φιανεται οτι θες ψηλοτερες τιμες για τα τρια κερδη κυριως για το Ki και μετα για το Kp. Για χαμηλα setpoint παει λιγο κατα διαολου. Αν και με τις νεες τιμες κερδων παλι εχει θεμα (αν υποθεσουμε οτι τα βρηκες σωστα) μπορει να βγαινεις εκτος γραμμικης περιοχης. Βασικος περιορισμος του PID ειναι οτι δουλευει μονο σε γραμμικα συστηματα. Εχεις βαλει την εισοδο στο Α0 ετσι? Τελος max ampere digital output για arduino uno ειναι 40mΑ Επεξ/σία 27 Οκτωβρίου 2015 από Rayven
capthookb Δημοσ. 27 Οκτωβρίου 2015 Μέλος Δημοσ. 27 Οκτωβρίου 2015 Ναι, γνωρίζω για τις διάφορες μεθόδους που μπορείς να χρησιμοποιήσεις για να βρεις τα σωστά Kp, Ki, Kd. Ωστόσο ανεξαρτήτως των σταθερών αυτών, όπως και της Input, όταν το Output έχει μια τιμή, έστω μικρή, αυτή θα πρέπει να μεταφράζεται σε παροχή ενέργειας στο σύστημα. Πιο απλά, το windowsize=4000msec. To Output παραπάνω, υπολογίζεται κάπου στα ~230msec. Δηλαδή μέσα στο διάστημα των 4 δευτερολέπτων θα έπρεπε να δουλεύει για 230msec μια φορά. Ή σε διάστημα 8 δευτερολέπτων να δουλεύει 460msec κτλ. Ενώ στο παραπάνω παράδειγμα φαίνεται πως πέρασαν 4 δευτερόλεπτα ενώ το ρελέ δούλεψε μόνο στην αρχή του 1ου χρονικού παραθύρου. Γράφοντας τα παραπάνω έκανα τις πράξεις και διαπίστωσα κάτι πολύ ενδιαφέρον. Η πρώτη λειτουργία του ρελέ είναι για χρόνο (833-67)=766msec, παρ'όλο που το Output ορίζει 214-215. Το 766/215 είναι περίπου 4. Δηλαδή ο χρόνος που δούλεψε ισοδυναμεί με χρονικό διάστημα 4 παλμών συνολικά. Περίπου το ίδιο ισχύει και για τους επόμενους χρόνους. Το ds18b20 δεν το έχω συνδέσει στο Α0. Είναι ψηφιακός αισθητήρας που χρησιμοποιεί την τεχνολογία 1-wire και μπορείς να συνδέσεις όσους αισθητήρες θες σε σειρά (ή τουλάχιστον πολλούς). Συνδέεται σε ψηφιακή είσοδο του arduino, καθώς και στα +5V, GND. Το ρεύμα που ενεργοποιεί το πηνίο του ρελέ δεν τροφοδοτείται από την ψηφιακή έξοδο του arduino, αλλά από το pin που παρέχει +5V, και η οποία έχει max 200ma ένταση ρεύματος. Θα μπορούσα να χρησιμοποιήσω εξωτερική τροφοδοσία για το module των ρελέ αλλά δουλεύει κι έτσι. Όταν ενεργοποιείται, το ρεύμα που πρέπει να παρέχει το arduino στην ψηφιακή του έξοδο είναι 0.35mA<40mA. https://ellipsistechnology.wordpress.com/2015/05/05/operating-a-12v-relay-from-a-5v-arduino-output/
Rayven Δημοσ. 27 Οκτωβρίου 2015 Δημοσ. 27 Οκτωβρίου 2015 Με τα ρελε οκ. Απλα ρωταω για να πιασουμε ολες τις περιπτωσεις Στον κωδικα σου γραφεις Input = analogRead(0); Δηλαδη περιμενει να διαβασει αναλογικο μεγεθος στην Α0 εισοδο. Αφου δε συνδεεις τιποτα εκει σαν input διαβαζει 1023. Επισης ο αισθητηρας θερμοκρασιας που εχεις συνδεσει στο 2 δεν συμμετεχει πουθενα στον κωδικα σου.
capthookb Δημοσ. 27 Οκτωβρίου 2015 Μέλος Δημοσ. 27 Οκτωβρίου 2015 Ναι, βασικά δε χρησιμοποιώ τον κώδικα που φαίνεται στο 1ο post αυτούσιο. Το γράφω κι εκεί πως το πήρα σαν βάση. Αυτός που παραθέτω πιο πάνω είναι ο κώδικας, που υπάρχει σαν παράδειγμα στη σελίδα της PID βιβλιοθήκης. Εγώ έχω κάνει κάποιες αλλαγές, χρησιμοποιώ δηλαδή τον αισθητήρα, κάποιες συναρτήσεις που δέχονται εντολές σειριακά (π.χ. αλλαγή setpoint κτλ). Ωστόσο το κομμάτι που εκτελεί μέσα στο loop, όπως και η λογική του windowsize και τα if controls είναι ολόιδια με τον κώδικα παραπάνω.
Rayven Δημοσ. 27 Οκτωβρίου 2015 Δημοσ. 27 Οκτωβρίου 2015 Εγω μιλαω με αυτα που βλεπω. Απο εκει και περα ξαναγυρνωντας στο προηγουμεο σου post Ναι, γνωρίζω για τις διάφορες μεθόδους που μπορείς να χρησιμοποιήσεις για να βρεις τα σωστά Kp, Ki, Kd. Ωστόσο ανεξαρτήτως των σταθερών αυτών, όπως και της Input, όταν το Output έχει μια τιμή, έστω μικρή, αυτή θα πρέπει να μεταφράζεται σε παροχή ενέργειας στο σύστημα. Πιο απλά, το windowsize=4000msec. To Output παραπάνω, υπολογίζεται κάπου στα ~230msec. Δηλαδή μέσα στο διάστημα των 4 δευτερολέπτων θα έπρεπε να δουλεύει για 230msec μια φορά. Ή σε διάστημα 8 δευτερολέπτων να δουλεύει 460msec κτλ. Ενώ στο παραπάνω παράδειγμα φαίνεται πως πέρασαν 4 δευτερόλεπτα ενώ το ρελέ δούλεψε μόνο στην αρχή του 1ου χρονικού παραθύρου. Γράφοντας τα παραπάνω έκανα τις πράξεις και διαπίστωσα κάτι πολύ ενδιαφέρον. Η πρώτη λειτουργία του ρελέ είναι για χρόνο (833-67)=766msec, παρ'όλο που το Output ορίζει 214-215. Το 766/215 είναι περίπου 4. Δηλαδή ο χρόνος που δούλεψε ισοδυναμεί με χρονικό διάστημα 4 παλμών συνολικά. Περίπου το ίδιο ισχύει και για τους επόμενους χρόνους. Πιθανα θεματα που μου ερχονται στο μυαλο 1. Μπορει τα ρελε που εχεις να μην ειναι αρκετα γρηγορα ωστε να ανταποκρινονται στις αλλαγες της εξοδου. Κατι τετοιο μπορει να δικαιολογησει και την λειτουργια σταθερα καθε 4 παλμους. 2. Για να κλεισει τις επαφες του ενα ρελε θελει καποιον χρονο. Αυτος ειναι ο χρονος λειτουργιας και καποια χρονικη καθυστερηση. Το ρευμα ενεργοποιησης πρεπει να διατηρειται για ολον αυτον τον χρονο ωστε να κλεισουν τελικα οι επαφες. Αν αλλαζει πολυ γρηγορα η εξοδος μπορει να μη φτανει. 3. Σφαλμα κβαντησης.
capthookb Δημοσ. 27 Οκτωβρίου 2015 Μέλος Δημοσ. 27 Οκτωβρίου 2015 Ο λόγος που δεν ενεργοποιείται το ρελέ, φαίνεται από τα νούμερα στο post#5. To if(Output > now - windowStartTime) είναι τις περισσότερες φορές true και επομένως ο έλεγχος κλείνει το ρελέ: digitalWrite(RelayPin,HIGH); (Στο HIGH απενεργοποιείται το πηνίο και στο LOW ενεργοποιείται) Δηλαδή είναι καθαρά θέμα λογικής του κώδικα. Έχω δει τα ρελέ να ανοιγοκλείνουν πολύ πιο γρήγορα.
Rayven Δημοσ. 27 Οκτωβρίου 2015 Δημοσ. 27 Οκτωβρίου 2015 Ο λόγος που δεν ενεργοποιείται το ρελέ, φαίνεται από τα νούμερα στο post#5. To if(Output > now - windowStartTime) είναι τις περισσότερες φορές true και επομένως ο έλεγχος κλείνει το ρελέ: digitalWrite(RelayPin,HIGH); (Στο HIGH απενεργοποιείται το πηνίο και στο LOW ενεργοποιείται) Δηλαδή είναι καθαρά θέμα λογικής του κώδικα. Έχω δει τα ρελέ να ανοιγοκλείνουν πολύ πιο γρήγορα. Ετσι οπως ειδα και το παραδειγμα, καταλαβαινα οτι high ενεργοποιειται ρελε εχοντας συνδεσει το κυκλωμα ισχυος στις normally open (α επαφες) του. Ενεργοποειται το ρελε, αναβει η αντισταση. To συγκεκριμενο module απο οτι βλεπω εχει μονο normally closed (β επαφες). Οπως το καταλαβαινω πρεπει να βαλεις αναποδα τα high και low στον κωδικα. Το παραδειγμα δεν αναφερει τι module χρησιμοποιεις.
capthookb Δημοσ. 28 Οκτωβρίου 2015 Μέλος Δημοσ. 28 Οκτωβρίου 2015 Κι εγώ αρχικά έτσι νόμιζα. Με HIGH έπρεπε να ενεργοποιείται το ρελέ, αλλά ήταν ανάποδα και έτσι τα άλλαξα στον κώδικα. Το module έχει και normally open και normally closed επαφή (3 pin στο σύνολο ανά ρελέ).
capthookb Δημοσ. 1 Νοεμβρίου 2015 Μέλος Δημοσ. 1 Νοεμβρίου 2015 Λοιπόν Rayven, βρήκα αυτό που έψαχνα. Για να δουλέψει ο κώδικας παραπάνω, πρέπει o χρόνος που εκτελείται κάθε φορά το loop να είναι όσο πιο μικρός γίνεται. Έτσι η σύγκριση μεσα στο if γίνεται πολλές φορές για κάθε χρονικό περιθώριο των 4000msec, και ο κώδικας έχει τη δυνατότητα να ενεργοποιήσει το ρελέ αρκετά κοντά στο χρόνο που υπολογίζεται. Στο παράδειγμα παραπάνω, κάθε loop επαναλαμβάνεται μετά από 766 msec και η Output είναι μικρότερη αυτού του χρόνου. Άρα κατά τύχη άνοιγε το ρελέ και έμενε ανοιχτό για χρόνους πολλαπλάσιους του χρόνου εκτέλεσης του loop (δηλαδή Νx766msec). Η αιτία ήταν η ακρίβεια που είχα ορίσει στον αισθητήρα, ο οποίος διαβάζει θερμοκρασία σε κάθε loop. Κατά το setup ορίζεται η ακρίβεια του αισθητήρα, και δεν ήξερα πως όσο μεγαλύτερη τόσο καθυστερεί ο αισθητήρας να επιστρέψει την τιμή της θερμοκρασίας (και άρα το loop). Αρχικά το είχα ρυθμίσει στα 12bit. Ρίχνοντάς την στα 10bit ο χρόνος του loop έπεσε στα 200msec, ενώ στα 9bit είναι κάπου στα 110msec. Έτσι τώρα το χρονικό διάστημα των 4000msec, ελέγχεται κάθε 110msec, δηλαδή περίπου 36 φορές. Άρα η ευχέρεια του ρελέ να δουλέψει για π.χ. 200msec στο διάστημα του παραθύρου είναι εφικτή. Και τώρα που το σκέφτομαι, σημασία δεν έχει ο απόλυτος χρόνος του κάθε loop, αλλά ο σχετικός χρόνος WindowSize/looptime. Αν για παράδειγμα με χρόνο loop 766msec, είχα ένα παράθυρο 28000msec, πάλι θα είχα 36 ελέγχους ανα παράθυρο και αρκετά μεγαλύτερη ανάλυση ελέγχων, άρα και λειτουργίας. Εδώ μάλλον μπαίνει και ο παράγοντας του τι προσπαθω να ελέγξω και πως ανταποκρίνεται στα διαφορετικά windowsize(s). Ευχαριστώ πάντως για τη βοήθεια! Επιτέλους το κατάλαβα
Rayven Δημοσ. 3 Νοεμβρίου 2015 Δημοσ. 3 Νοεμβρίου 2015 Συγχαρητηρια που το βρηκες! Καλα εκανες και ενημερωσες το thread και για δικη μου περιεργια και μηπως βοηθηθει καποιος αλλος που θα ασχοληθει με το θεμα. Δεν ειχα φτιαξει ποτε PID απο το μηδεν. Στη σχολη ειχαμε ετοιμους controllers και μας απασχολουσε μονο η σωστη ρυθμιση των τριων κερδων. Μαλιστα τους ψιλοσνομπαραμε γιατι τους θεωρουσαμε generic δηλ "δια πασαν νοσον και πασαν..." και νοιαζομασταν πιο πολυ για μη γραμμικα συστηματα.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα