Αναλογική είσοδος και έξοδος

Σε αυτή την ενότητα, θα μιλήσουμε για την διαφορά μεταξύ ψηφιακών και αναλογικών σημάτων καθώς και το πως θα μετράμε αναλογικά σήματα μέ τα πινς αναλογικής εισόδου του Arduino.

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

Ανόμοια με τα ψηφιακά σήματα, τα αναλογικά σήματα μπορεί να μεταβάλλονται με αναρίθμητο αριθμό από βήματα σε μια περιοχή μεταξύ δυο τάσεων. Για παράδειγμα η επόμενη εικόνα δείχνει ένα αναλογικό σήμα ενός ημιτονοειδούς κύματος. Σημείωση: αυτό το αναλογικό σήμα, η τάση αλλάζει ομαλά με την πάροδο του χρόνου, μεταξύ των επιπέδων high και low.

Αναλογικές εισόδοι

Στην πλατφόρμα Arduino, το επίπεδο HIGH είναι κοντά στα 5V και το επίπεδο LOW είναι κοντά στα 0V ή GND. Μπορούμε να μετρήσουμε το επίπεδο της τάσης ενός αναλογικού σήματος χρησιμοποιώντας τις έξι αναλογικές εισόδους του Arduino. Αυτές οι αναλογικές είσοδοι μπορούν να μετρούν τάσεις με ασφάλεια όταν κυμαίνονται μεταξύ 0V και 5V.

Μέτρηση μιας εξωτερικής τάσης με το Arduino

Χρησιμοποιώντας την συνάρτηση analogRead(), το Arduino επιστρέφει ένα αριθμό μεταξύ 0 και 1.023 ανάλογα με την τάση που εφαρμόζεται στο αντίστοιχο αναλογικό πιν. Για παράδειγμα, μπορούμε να χρησιμοποιήσουμε την συνάρτηση analogRead(0) για να εκχωρήσουμε την τιμή της τάσης του αναλογικού πιν μηδέν (0) στην ακέραια μεταβλητή a:

int a;
a = analogRead(0); //read analog input pin 0 (A0)
                   //returns 0 to 1023 which is usually 0.000 to 4.995

Παράδειγμα – Δοκιμαστής μπαταρίας

Οι μπαταρίες μονής κυψέλης έχουν μεγάλη διάδοση, που αναφέρονται με τους τύπους ΑΑ, ΑΑΑ, C ή D και χρησιμοποιούνται στα χειριστήρια απομακρυσμένου ελέγχου, στα ρολόγια ή στα παιδικά παιχνίδια. Αυτές οι μπαταρίες αναπτύσσουν τάση στα άκρα τους λιγότερο από 5V, έτσι μπορούμε να μετρήσουμε την τάση που δίνουν αυτές οι μπαταρίες, με ασφάλεια, χρησιμοποιώντας την πλατφόρμα Arduino

Ο στόχος

Οι μπαταρίες μονής κυψέλης όπως οι ΑΑ έχουν αρχική τάση περίπου 1.6V όταν είναι καινούργιες και μετά η τάση τους μειώνεται με τη χρήση τους. Σε αυτή την εργασία θα φτιάξουμε μια εφαρμογή με την οποία θα μετράμε την τάση της μπαταρίας και θα την εκφράσουμε με την ένδειξη τριών LEDs. Με αυτή την εφαρμογή, θα παίρνουμε την τιμή που επιστρέφει η συνάρτηση analogRead() και θα την μετατρέπουμε σε volts με τον εξής τρόπο: Η μεγίστη τάση που μπορεί να διαβάσει είναι 5V, έτσι διαιρώντας την τιμή 5 δια 1,024 (ο αριθμός των πιθανών τιμών) δίνει τιμή ίση με 0,0048 ανά βήμα. Επομένως εάν η συνάρτηση analogRead() επιστρέφει 512, πολλαπλασιάζουμε αυτή την τιμή με 0,0048 η οποία δίνει τάση 2.4576V.

Το σχηματικό

Το σχηματικό του δοκιμαστή μπαταρίας φαίνεται στο παρακάτω σχήμα. Στο αριστερό μέρος της, όπως μπορείς να δεις, υπάρχουν δυο ακροδέκτες σημειούμενοι με + και -. Σε αυτά τα δυο σημεία συνδέεται η υπό έλεγχο μπαταρία. Η θετική πλευρά της μπαταρίας πρέπει να συνδεθεί στον θετικό ακροδέκτη του δοκιμαστή και η αρνητική πλευρά με τον αρνητικό ακροδέκτη.

Ο κώδικας

// Project 5 - Creating a Single – Cell Battery Tester
#define newLED 2    // green LED ‘new’
#define okLED  4    // yellow LED ‘ok’
#define redLED  6   // red LED ‘old’
int analogValue = 0;
float voltage = 0;
int ledDelay = 2000;
void setup()
{
    pinMode(newLED, OUTPUT);
    pinMode(okLED, OUTPUT);
    pinMode(oldLED, OUTPUT);
}
void loop()
{
    analogValue = analogRead(0);
    voltage = 0.0048*analogValue;
    if(voltage >= 1.6)
    {
         digitalWrite(newLED, HIGH);
         delay(ledDelay);
         digitalWrite(newLED, LOW);
     }
      else if(voltage < 1.6  &&  voltage > 1.4)
      {
          digitalWrite(okLED, HIGH);
          delay(ledDelay);
          digitalWrite(okLED, LOW);
      }
      else if(voltage <=1.4)
      {
           digitalWrite(oldLED, HIGH);
           delay(ledDelay);
           digitalWrite(oldLED, LOW);
       }
}

Σε αυτό τον κώδικα το Arduino παίρνει την τιμή που μετρά στο αναλογικό πιν 0 και το μετατρέπει σε τάση. Θα δούμε τον τύπο τύπου δεδομένων που μπορεί να πάρει μια μεταβλητή στην επόμενη ενότητα. Θα δούμε ακόμα ποιες αριθμητικές πράξεις μπορούμε να κάνουμε με τις μεταβλητές. Επίσης θα δούμε τις λογικές εκφράσεις που μπορούμε να κάνουμε με τους λογικούς και σχεσιακούς τελεστές.

Βελτιώνοντας την ακρίβεια αναλογικών μετρήσεων

Όπως επιδείξαμε στο παράδειγμα, η συνάρτηση analogRead() επιστρέφει μια ακέραια τιμή ανάλογα με την τάση μεταξύ 0 και 5V που εφαρμόζεται στην αναλογική είσοδο. Η ανώτερη τιμή (5V) είναι η τάση αναφοράς, που είναι η μέγιστη τάση που η αναλογική είσοδο του Arduino δέχεται και στην οποία η συνάρτηση επιστρέφει την υψηλότερη τιμή που είναι 1023.

analogRead(0)  // Read the voltage from the analoge pin A0

Για να αυξήσουμε την ακρίβεια του διαβάσματος μικρότερων τάσεων, μπορούμε να χρησιμοποιήσουμε μια μικρότερη τάση αναφοράς. Για παράδειγμα αν η τάση αναφοράς είναι για παράδειγμα 2V, η τάση από 0 έως 2V στην αναλογική είσοδο παρίσταται αναλογικά από την συνάρτηση analogeRead(A0) με μια τιμή μέσα στο εύρος 0 έως 1,023 στην οποία η τιμή 1,023 να αντιστοιχεί στα 2V

Χρησιμοποιώντας μια εξωτερική τάση αναφοράς

AREF pin

Η πρώτη μέθοδος χρήσης τάσης αναφοράς είναι με την εφαρμογή τάσης στο πιν AREF (analog reference). Συνδέουμε τον θετικό ακροδέκτη της τάσης αναφορά στο πιν AREF του Arduino και τον αρνητικό ακροδέκτη με το GND του Arduino. Η τάση αναφοράς πρέπει να είναι μικρότερη από 5V, ενώ η τάση στην αναλογική είσοδο του Arduino δεν πρέπει να υπερβαίνει την τάση αναφοράς. Ένας απλούστερος τρόπος για να δημιουργήσουμε μια τάση αναφοράς μικρότερη από 5V είναι χρησιμοποιώντας τον διαιρέτη τάσης με δυο αντιστάσεις όπως φαίνεται στο παρακάτω σχήμα.

Οι τιμές των αντιστάσεων R1 και R2 ορίζουν την τάση αναφοράς σύμφωνα με τη σχέση:

Vout είναι η τάση αναφοράς και Vin η τάση τροφοδοσίας. Οι R1 και R2 είναι αντιστάσεις εκφρασμένες σε ohms.

Ο απλούστερος τρόπος για να διαιρέσεις την τάση Vin στο μισό, είναι εκλέγοντας τις αντιστάσεις R1 και R2 στην ίδια τιμή, για παράδειγμα 10kΩ η κάθε μια. Εδώ θα πρέπει να χρησιμοποιήσεις αντιστάσεις με την μικρότερη ανοχή που μπορείς να βρεις, για παράδειγμα 1 τοις εκατό. Θα πρέπει να επιβεβαιώσεις τις τιμές τους μετρώντας τες με ένα πολύμετρο και χρησιμοποιούμε την τιμή των αντιστάσεων εκείνη που δίνει το πολύμετρο. Περαιτέρω είναι καλή ιδέα να τοποθετήσεις ένα πυκνωτή 100nF μεταξύ AREF και GND για την αποφυγή του θορύβου.

Όταν χρησιμοποιείς εξωτερική τάση αναφοράς, εισήγαγε την επόμενη γραμμή μέσα στην συνάρτηση void setup() του κώδικα.

analogReference(EXTERNAL); // select ARFF pin for reference voltage

Χρησιμοποιώντας την εσωτερική τάση αναφοράς

Το Arduino Uno έχει μια εσωτερική τάση αναφοράς ίση με 1.1V. Εάν αυτό σας βολεύει δεν χρειάζονται επιπρόσθετα εξαρτήματα. Σε αυτή την περίπτωση πρόσθεσε την ακόλουθη γραμμή στη συνάρτηση void setup() του κώδικα.

analogeReference(INTERNAL); // select internal 1.1V reference voltage.

Αναλογική έξοδος στο Arduino

Αν συνδέαμε ένα LED σε μια έξοδό του Arduino, θα μπορούσαμε να ελέξουμε την φωτεινότητα του, με άναμμα και σβήσιμο του, χρησιμοποιώντας την εντολή digitalWrite(). Αλλά ένας άλλος καλύτερος τρόπος είναι η χρήση της διαμόρφωσης πλάτους παλμών PWM. Για να δημιουργήσουμε το σήμα PWM χρησιμοποιούμε την συνάρτηση

analogWrite(pin, duty_cycle);

Με αυτή την συνάρτηση στέλνουμε παλμούς ίδιας συχνότητας περίπου 500 κύκλους το δευτερόλεπτο, διαμορφωμένους κατά πλάτος. Το όρισμα pin της συνάρτησης ορίζει τον ακροδέκτη εξόδου και το όρισμα duty cycle ορίζει το επί τις εκατό το πλάτος on/off του τετραγωνικού σήματος. Συγκεκριμένα, το duty cycle ορίζεται το ως προς τις εκατό που το σήμα είναι HIGH σε σχέση με την περίοδο του σήματος και είναι μια τιμή μεταξύ των ορίων 0 και 255. Η τιμή 0 εκφράζει 0% duty cycle ενώ η τιμή 255 εκφράζει 100% duty cycle.

Δεν μπορούμε να ορίσουμε και να πάρουμε PWM τάση από όλα τα pins του Arduino. Τα pins που είναι δυνατό να πάρουμε PWM τάση είναι εκείνα, που π.χ. στο Arduino Uno έχουν την περισπωμένη δίπλα στο όνομα τους.

Στην εικόνα φαίνονται διάφορα PWM duty cycles. Η γεμάτη γκρί περιοχή παριστάνει το χρόνο του το LED ανάβει. Όπως μπορείς να δεις ο χρόνος ανά κύκλο που το LED ανάβει αυξάνει με το duty cycle.

Παράδειγμα

Τώρα ας κάνουμε τα παραπάνω πράξη στο κύκλωμα. Εισήγαγε τον επόμενο κώδικα στο IDE και μετά ανέβασε το στο Arduino:

// Project 3 – Demonstrating PWM
int d = 5;
void setup()
{
pinMode(3, OUTPUT);  //LED control pin is 3, a PWM capable pin
}
void loop()
{
    for(int a=0; a<256; a++)
    {
        analogWrite(3, a);
        delay(d);
     }
     for(int a=255; a>=0; a--)
      {
          analogWrite(3, a);
          delay(d);
      }
      delay(200);
}

Το LED το οποίο είναι συνδεμένο στο πιν 3 επιδεικνύει το “εφέ της αναπνοής” καθώς το duty cycle αυξάνει και μειώνεται. Με άλλα λόγια, το LED ανάβει με αυξανόμενη φωτεινότητα μέχρι να λάμψει πλήρως και μετά αντίστροφα.