Ψηφιακά πινς εισόδου εξόδου

Στους διακόπτες push button εμφανίζεται ένα φαινόμενο που ονομάζεται αναπήδηση διακόπτη, το οποίο αναφέρεται στην ιδιότητα του διακόπτη να τίθεται on και off με μεγάλη συχνότητα τη στιγμή που πατάμε η απελευθερώνουμε τον διακόπτη.

Η αναπήδηση ενός διακόπτη μπορεί να επιδειχθεί με ένα ψηφιακό παλμογράφο, ένα όργανο που απεικονίζει την τάση σε συνάρτηση με τον χρόνο. Για παράδειγμα θεωρούμε το παρακάτω σχήμα, στο οποίο ο παλμογράφος δείχνει την αναπήδηση διακόπτη. Το πάνω μισό της εικόνας δείχνει το αποτέλεσμα της χρήσης του μπουτόν αρκετές φορές. Μεγεθύνοντας το μέτωπο της πτώσης της τάσης που προκαλεί ο διακόπτης, το αποτέλεσμα φαίνεται στο κάτω μισό της εικόνας. Κατα την πίεση του διακόπτη εμφανίζονται αιχμές όπως φαίνονται στο σχήμα.

Εργασία 4

Σε αυτή την εργασία έχουμε ένα διακόπτη, ο οποίος ανάβει ένα LED για μισό δευτερόλεπτο όταν πατηθεί.

Αλγόρηθμος
1] Ανιχευσε αν το μπουτόν έχει πατηθεί
2] Εάν ο διακόπτης έχει πατηθεί, τότε αναψε το LED για μισό δευτερόλεπτο και μετά σβήσε το.
3] Εάν ο διακόπτης δεν έχει πατηθεί μην κάνεις τίποτα
4] Επανάληψη

Το σχηματικό κύκλωμα

Πρώτα σχηματίζουμε το κύκλωμα πάνω στο breadboard όπως στο σχηματικό της παρακάτω εικόνας. Δώσε προσοχή στο πως η αντίσταση 10kΩ συνδέεται μεταξύ GND και στο ψηφιακό πιν 7. Ονομάζουμε αυτή την αντίσταση pull-down γιατί “τραβά” την τάση του ψηφιακού πιν σχεδόν στο μηδέν. Περεταίρω, με την τοποθέτηση ενός πυκνωτή 100nF παράλληλα στην αντίσταση 10kΩ δημιουργούμε ένα κύκλωμα απαλλαγμένο από αναπηδήσεις.

Όταν ο διακόπτης πιέζεται το ψηφιακό πιν τίθεται αμέσως σε δυναμικό HIGH. Αλλά όταν ο διακόπτης απελευθερώνεται, το ψηφιακό πιν 7, “τραβιέται κάτω στο GND δια μέσου της αντίστασης 10kΩ και μαζί με τον εκτυπωτή 100nF δημιουργούν μια πολύ μικρή καθυστέρηση. Με αυτό τον τρόπο εξαλείφονται οι αναπηδήσεις και αποτρέπονται στο λάθος διάβασμα των τάσεων.

Η παρακάτω εικόνα δείχνει την υλοποίηση του κυκλώματος στο breadboard.

Ο κώδικας

Ανέβασε στο Arduino τον ακόλουθο κώδικα:

//Project 4 -Demonstrating a Digital Input
#define LCD 12
#define BUTTON 7
void setup()
{
    pinMode(LED, OUTPUT);  // output for the LED
    pinMode(BUTTON, INPUT);  //input for the button
}
void loop()
{
     if(digitalRead(BUTTON)==HIGH)
     {
           digitalWrite(LED, HIGH);  // turn on the LED
           delay(500);
           digitalWrite(LED, LOW);  // turn off the LED
     }
}

Μετά που ανεβάσεις τον κώδικα πάτησε στιγμιαία το μπουτόν και τότε το LED θα ανάψει για μισό δευτερόλεπτο.

Τροποποιώντας τον κώδικα

Μετά την επιτυχία της προηγούμενης εργασίας, προσπάθησε να τροποποιήσεις τον κώδικα, όπως για παράδειγμα τροποποίησε το χρόνο που ανάβει το LED ή την προσθήκη push button στο κύκλωμα της εργασίας 3.

Πως δουλεύει ο κώδικας

Ας εξετάσουμε τα καινούργια στοιχεία στην εργασία 4, ειδικότερα #define, πινς ψηφιακής εισόδου και την έκφραση if-then.

Δημιουργώντας σταθερές με την #define

Πριν την συνάρτηση void setup() έχουμε χρησιμοποιήσει την έκφραση #define για την δημιουργία σταθερών μεταβλητών. Καθώς ο κώδικας μεταφράζεται από τον κομπάιλερ, το περιβάλλον IDE αντικαθιστά κάθε υπόδειγμα που ορίζεται από την define με τον αριθμό που ακολουθεί στην έκφραση αυτή. Για παράδειγμα, όταν το IDE βλέπει LED στην έκφραση digitalWrite(LED, LOW) το αντικαθιστά με τον αριθμό 12.

Βασικά χρησιμοποιούμε την εντολή #define για να δώσουμε όνομα στα ψηφιακά πινς στα οποία είναι συνδεμένα το LED και το button. Ας σημειώσουμε ότι δεν χρησιμοποιούμε ερωτηματικό στο τέλος μετά την #define. Είναι καλή τακτική να δίνομε ετικέτες στο ψηφιακά πινς και στις άλλες σταθερές τιμές (όπως στη χρονική καθυστέρηση). Με αυτό τον τρόπο, για τον λόγο που η ίδια η μεταβλητή χρησιμοποιείται επαναλαμβανόμενα στο κώδικα, δεν θα χρειαστεί να την αλλάξεις περισσότερες από μια φορές. Σε αυτό το παράδειγμα LED χρησιμοποιείται τρεις φορές στο κώδικα και για να επέμβεις σε αυτές τις τιμές απλά άλλαξε την τιμή στην έκφραση #define.

Διάβασμα πιν ψηφιακής εισόδου

Για το διάβασμα της κατάστασης ενός διακόπτη, πρέπει να δηλώσουμε ως INPUT το πίν στο οποίο είναι συνδεδεμένος ο διακόπτης, μέσα στη συνάρτηση in void setup() χρησιμοποιώντας την ακόλουθη έκφραση

pinMode(BUTTON, INPUT);

Μετά, για να δούμε εάν ο διακόπτης που είναι συνδεμένος σε ένα ψηφιακό πιν, το οποίο τροφοδοτείται με μια τάση, είναι πατημένος χρησιμοποιούμε, την εντολή digitalRead(pin) όπου pin είναι η ψηφιακή είσοδος πιν που πρόκειται να διαβαστεί. Η συνάρτηση επιστρέφει είτε HIGH (τάση κοντά στα 5V) ή LOW τάση κοντά στα 0V στο ψηφιακό πιν)

Κάνοντας επιλογές με την εντολή if

Χρησιμοποιώντας την εντολή if μπορούμε να κάνουμε επιλογές στον κώδικα μας και να πούμε στο Arduino να τρέξει διαφορετικό κώδικα, βασισμένο στην επιλογή if. Για παράδειγμα στον κώδικα της εργασίας 4, δηλαδή στον κώδικα

// Listing 4 -2
if(digitalRead(BUTTON) == HIGH)
{
   digitalWrite(LED, HIGH);   //  turn on the LED
   delay(500);
    digitalWrite(LED, LOW);   // turnoff the LED
}

Η πρώτη γραμμή στον κώδικα ξεκινά με την εντολή if η οποία ελέγχει μια συνθήκη. Εάν η συνθήκη είναι αληθείς (δηλαδή η τάση είναι HIGH), αυτό σημαίνει ότι το μπουτόν έχει πατηθεί και ο κώδικας που ακολουθεί μέσα στις αγκύλες θα τρέξει.

Για να ορίσουμε εάν το μπουτόν έχει πατηθεί (digitalRead(BUTTON) έχει τιμή HIGH) χρησιμοποιούμε ένα τελεστή σύγκρισης, ένα διπλό σύμβολο ίσον (==). Εάν στον κώδικα αντικαταστήσουμε το == με != (όχι ίσο με), τότε το LED θα σβήσει όταν το μπουτόν πατηθεί.

Δεν θα πρέπει να συγχέουμε το απλό σύμβολο ισότητας (=)που σημαίνει “κάνε ίσο με” με τον τελεστή σύγκρισης (==) που σημαίνει “έλεγξε εάν είναι ίσο με.

Κάνοντας περισσότερες επιλογές με την εντολή if-then-else

Μπορείς να κάνεις και μια άλλη δράση με την εντολή if χρησιμοποιώντας την έκφραση else. Για παράδειγμα, μπορούμε να ξαναγράψουμε τον κώδικα 4-1 όπως τον κώδικα 4-3, στο οποίο το LED ανάβει εάν το μπουτόν πιέζεται, διαφορετικά δεν θα ανάβει. Χρησιμοποιώντας την εντολή else οδηγεί το Arduino να τρέξει ένα άλλο κομμάτι κώδικα εάν η συνθήκη στην έκφραση if δεν είναι αληθείς.

// Listing 4-3
#define LED   12
#define BUTTON 7
void setup()
{
    pinMode(LED, OUTPUT);   // output for the LED
    pinMode(BUTTON, INPUT);  //  input for the button
}
void loop()
{
    if(digitaRead(BUTTON) == HIGH)
    {
        digitalWrite(LED, HIGH);
     }
     else
     {
         digitalWrite(LED, LOW);
     }
}

Λογικές μεταβλητές

Μερικές φορές θα χρειαστεί να ορίσεις εάν μια ποσότητα είναι σε μια από τις δυο καταστάσεις όπως είτε on ή off. Μια λογική μεταβλητή στην ορολογία των υπολογιστών ονομάζεται και “bit” και μπορεί να πάρει μια από δυο τιμές: μηδέν (0, false) ή ένα (1, true). Εδώ είναι όπου μια λογική μεταβλητή είναι χρήσιμη: Μπορεί να είναι μόνο true (αληθής) ή false (ψευδής). Όπως και με τις άλλες μεταβλητές, χρειάζεται να την δηλώσουμε με τύπο boolean για να την χρησιμοποιήσουμε.

boolean raining = true; // create the variable “raining” and first make it true

Μέσα στον κώδικα, μπορείς να αλλάξεις την τιμή της λογικής μεταβλητής με μια απλή επανεκχώρηση:

raining = false;

Είναι απλό το να χρησιμοποιείς λογικές μεταβλητές στο να κάνεις επιλογές χρησιμοποιώντας μια έκφραση if. Επειδή στις λογικές συγκρήσεις μεταξύ λογικών μεταβλητών με τους τελεστές == και != έχουμε τιμή true ή false μπορούν να χρησιμοποιηθούν με την εντολή if ή while. Ακολουθεί ένα παράδειγμα:

boolean raining = true;
boolean summer = false;
if(raining == true)
{
     if(summer != true)
     {
          // This block is executed when it is raining ant not summer
      }
}

Λογικοί τελεστές

Μπορούμε να χρησιμοποιήσουμε διάφορους τελεστές στο να κάνουμε επιλογές, όπως οι τελεστές not(!), and(&&), or(||).

Ο τελεστής not: Ο τελεστής not χρησιμοποιείται με το σύμβολο του θαυμαστικού (!). Για μια λογική μεταβλητή είναι true με τον τελεστή not (!) παίρνει τιμή false. Ακολουθεί ένα παράδειγμα:

if( !raining)
{
     //This block is executed when it is not raining (raining == false)
}

Ο τελεστής and: Ο λογικός τελεστής and παρίσταται με το σύμβολο &&. Χρησιμοποιώντας τον τελεστή && (and) βοηθά να μειώσουμε τους ελέγχους με την εντολή if. Ο τελεστής and ενώνει δύο λογικές εκφράσεις. Ολόκληρη η λογική έκφραση είναι true όταν και οι δύο λογικές εκφράσεις είναι true. Ακολουθεί ένα παράδειγμα.

If(( raining == true ) && ( !summer ))
{
     //This block is executed when it is raining and not summer 
      //(raining == true and summer == false))
}

Ο τελεστής or: Ο λογικός τελεστής or παρίσταται με το σύμβολο ||. Ο τελεστής or ενώνει δύο λογικές εκφράσεις. Ολόκληρη η λογική έκφραση είναι true όταν μια από τις δύο (ή και οι δυο) λογικές εκφράσεις είναι true. Ακολουθεί ένα παράδειγμα:

if(( raining == true ) || (summer == true ))
{
    //This block is executed when it is either raining or summer
}

Κάνοντας δυο ή περισσότερες συγκρίσεις

Μπορείς να χρησιμοποιήσεις δυο ή περισσότερες λογικές συγκρίσεις στην ίδια εκφραση if. Ακολουθεί ένα παράδειγμα:

if(snow == true && rain == true && !hot)
{
   //This block is executed when it is snowing and raining and not hot
}

Μπορείς να χρησιμοποιείς παρενθέσεις για να καθορίσεις την σειρά των συγκρίσεων. Στο επόμενο παράδειγμα η σύγκριση μέσα στις παρενθέσεις ελέγχεται πρώτη, δίνοντας true ή false και μετά και μετά συγκρίνεται με την υπόλοιπη λογική έκφραση μέσα στην εντολή if – then.

If(( snow == true || rain == true) && hot == false))
{
    //This block is executed when it is either snowing or raining and not hot
}

Σε αυτά τα παραδείγματα οι λογικές μεταβλητές δεν είναι απαραίτητο να συγκρίνονται με ==true και ==false. Έτσι αν η λογική μεταβλητή raining έχει την τιμή true, η έκφραση raining == true έχει τιμή true, ενώ αν η λογική μεταβλητή raining έχει τιμή true,η έκφραση raining == false παίρνει την τιμή false . Έτσι ο κώδικας του προηγούμενου παραδείγματος είναι ισοδύναμος με τον ακόλουθο κώδικα:

if(( snow || raining) && !hot)
{
   //This block is executed when it is either snowing or raining and not hot
   // (snow is true OR rain is true) AND it is not hot
}

Στα προηγούμενα παραδείγματα οι snow, raining, summer και hot είναι λογικές μεταβλητές οι οποίες δηλώνονται και πέρνουν αρχικές τιμές πριν την συνάρτηση void setup() όπως για παράδειγμα τις ακόλουθες τιμές:

boolean snow=false, raining=true, summer=true, hot=false;