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

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

Μέχρι τώρα, στο κώδικα που γράψαμε για το Arduino, χρησιμοποιήσαμε ψηφιακά σήματα, στα οποια η τάση μπορεί να είναι ένα από δυο διακριτά επίπεδα HIGH και LOW. Ειδικότερα, χρησιμοποιούμε τις εντολές digitalWrite(pin, HIGH) και digitalWrite(pin, LOW) για να αναβοσβήνουμε ένα LED και την digitalRead() για να μετρήσουμε εάν ενα ψηφιακό πιν έχει τάση αναφορικα σε HIGH ή LOW. Η παρακάτω εικόνα είναι μια οπτική αναπαράσταση ενός ψηφιακού σήματος που εναλλάσσεται μεταξύ 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 δέχεται στην οποία η συνάρτηση επιστρέφει την υψηλότερη τιμή που είναι 1,023.

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

Για να αυξήσουμε την ακρίβεια για το διάβασμα μικρότερων τάσεων, μπορούμε να χρησιμοποιήσουμε μια μικρότερη τάση αναφοράς. Για παράδειγμα αν η τάση αναφοράς είναι για παράδειγμα 2V, η τάση από 0 έως 2V στην αναλογική είσοδο παρίσταται αναλογικά από την συνάρτηση analogeRead(A0) me μια τιμή μέσα στο εύρος 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 ορίζει το επί τις εκατό το πλάτος του τετραγωνικού σήματος. Συγκεκριμένα, το 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 ανάβει με αυξανόμενη φωτεινότητα μέχρι να λάμψει πλήρως και μετά αντίστροφα.