Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Σχεδιάζω την κατασκευή του ηλεκτρονικού μέρους μιας τηλεχειριζόμενης διπλής ανοιγόμενης αυλόπορτας.

Χρησιμοποιώ 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;

      }   

    }

 

Ευχαριστώ εκ των προτέρων, για οποιαδήποτε σκέψη και παρατήρηση.

  • Like 2
  • Απαντ. 38
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ.

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 πχ

Δημοσ.

Ευχαριστώ για τις πρώτες συμβουλές, έκανα την αλλαγή που προτείνεις.

 

Λοιπόν χρειάζομαι δύο χρόνους(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) 

δεν δούλεψε, δεν πειράζει, ας το αφήσουμε όπως το βρήκα.

Δημοσ.

Αντί του & δοκίμασε το AND. Επίσης αν δεν θέλεις delay που θα παγώνει το πρόγραμμα και δεν θα μπορείς κατά την διάρκεια να διαβάζεις εισόδους δοκίμασε interrupt ή απλά κάποια επαφή που θα σου δίνει το ΟΚ (θα διαβάζεις τάση) ότι η πόρτα έχει φτάσει στο μέγιστο άνοιγμα. Ή με το διάβασμα του ρεύματος, το "ζόρισμα" των μοτερ θα σου δίνει το ΟΚ ότι έφτασε στο μέγιστο ή βρήκε εμπόδιο. Καλύτερα με το ρεύμα πάντως.

 

 

Και φτιάξε λίγο τον κώδικα φαίνεται να υπάρχουν παραπάνω αγκύλες

Δημοσ.

Αδερφέ!

Η 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.. δες το). 

Δημοσ.

Δεν θες χρόνους. Θες state του project.

Είναι ανοικτή η πόρτα Α/Β ;

Μπορεί να ανοίξει η πορτ Α/Β;

Μπορεί να κλεισει η πόρτα Α/Β;

Έχει εμπόδια η πόρτα Α/Β;

Κλπ

Αν τα έχεις όλα αυτά, δεν θα χρειαστείς ούτε καν mc αλλά μόνο μερικούς τρανζίστορ και αντιστάσεις. Βέβαια καλύτερα ένα μc επειδή είναι πιο φτηνό από το να φτιαξεις πλακέτα.

Δημοσ.

Ευχαριστώ για τις απαντήσεις και τις προτάσεις σας.

Συγνώμη που δεν απάντησα νωρίτερα (αλλά χθες δεν ήταν δυνατόν)

 

Αυτό που χρειάζομαι είναι έναν μετρητή χρόνου

να ξεκινάει το μέτρημα των δευτερολέπτων από τη στιγμή που θα πατηθεί το μπουτόν,

ταυτόχρονα θα ξεκινήσει η πρώτη πόρτα να ανοίγει αν οι πόρτες είναι κλειστές,

ή να κλείνει η δεύτερη πόρτα αν αυτές είναι ανοιχτές.

Θέλω σε χρόνο 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 δεν διάβασα προσεκτικά το μήνυμά σου. Οι μηχανισμοί με τα μοτέρ έχουν ενσωματωμένους τερματικούς διακόπτες και στις δύο κατευθύνσεις εμείς δίνουμε ρεύμα και  αυτοί λειτουργούν, το σημείο τερματισμού ρυθμίζεται με κατσαβίδι, δεν χρειάζεται κάτι άλλο.

 

 

Άρα οι διακόπτες θα σου δώσουν το ΟΚ ότι η πόρτα έκλεισε? Όσο για το delay μόνο με interrupt. 

Δημοσ.

@marabatzis

 

Με αυτό που είπε ο παπί και αυτό που σου έγραψα εγώ, γίνεται δουλειά. Επιλέγεις να μην το διαβάσεις ή να μην ασχοληθείς... good luck!

Δημοσ.

Ερώτηση 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 τώρα...

 

Δημοσ.

Αδερφέ!

 

Η 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... τρίτωσε το κακό. 

 

Ξαναδιάβασε τα μηνύματα και εδώ είμαστε. 

Δημοσ.

Αδερφέ OP... τρίτωσε το κακό. 

 

Ξαναδιάβασε τα μηνύματα και εδώ είμαστε. 

Ευχαριστώ για την προσπάθειά σας να με βοηθήσετε.

 

Θα μελετήσω λίγο περισσότερο, είμαι ακόμη αρχάριος και κάποια πράγματα από αυτά που έγραψες ( ...να διαχωρίσεις την λογική από τις διεργασίες με functions....Την λογική άσε την στην "main" του sketch σου...) είναι ακόμη ακαταλαβίστικα.

Αν μπορούσαν να γίνουν περισσότερο ελληνικά, αν έχεις χρόνο, εγώ έτσι κι αλλιώς εγώ στην προσπάθεια είμαι.

Ένα απλός Ηλεκτρονικός είμαι, που προσπαθεί να ασχοληθεί με το arduino. Έως τώρα από προγραμματισμό μηδέν. 

Άλλος είναι OP!  :-D  :ph34r:

Συγνώμη τι είναι ΟΡ;

Δημοσ.

Ευχαριστώ για την προσπάθειά σας να με βοηθήσετε.

 

Θα μελετήσω λίγο περισσότερο, είμαι ακόμη αρχάριος και κάποια πράγματα από αυτά που έγραψες ( ...να διαχωρίσεις την λογική από τις διεργασίες με 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 θα το καταλάβεις πιο εύκολα). 

 

  1. global variables declaration, αυτό είναι πάνω-πάνω, εκεί όπου δηλώνεις τις μεταβλητές σου
  2. setup function, η function setup
  3. loop function, η κύρια function του arduino. Αφού κληθεί η setup και γίνει το setup των μεταβλητών, καλείται η loop και τρέχει συνέχεια. Εάν έγραφες C, θα καταλάβαινες την "παρομοίωση" με την main. 
  4. functions declaration, αυτό είναι μετά την loop όπου και εκεί γράφεις τις δικές σου functions (μπορείς να τις γράψεις και σε άλλο αρχείο, αλλά προς το παρόν δεν νομίζω να σε απασχολεί κάτι τέτοιο)

Οπότε, η main του sketch σου είναι η loop... απλά δεν θυμόμουν το όνομά της... και τώρα για να το γράψω έκανα scroll up. 

  • Like 1

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...