No history yet

Προηγμένος Χειρισμός Εισόδων/Εξόδων

Πέρα από το On/Off: Έλεγχος με PWM

Μέχρι τώρα, έχετε χρησιμοποιήσει τη συνάρτηση digitalWrite() για να ανάψετε ή να σβήσετε ένα LED. Αυτό είναι χρήσιμο, αλλά ο πραγματικός κόσμος σπάνια είναι τόσο απόλυτος. Τι γίνεται αν θέλετε να ρυθμίσετε τη φωτεινότητα ενός LED ή να ελέγξετε την ταχύτητα ενός κινητήρα; Για αυτές τις περιπτώσεις, το απλό ON/OFF δεν αρκεί. Χρειαζόμαστε κάτι ενδιάμεσο.

Εδώ έρχεται η Διαμόρφωση Εύρους Παλμών, ή αλλιώς (Pulse Width Modulation). Αντί να στέλνει μια σταθερή τάση, το PWM αλλάζει ταχύτατα μεταξύ HIGH και LOW. Η αναλογία του χρόνου που το σήμα παραμένει HIGH σε σχέση με τον συνολικό χρόνο ενός κύκλου ονομάζεται κύκλος εργασίας.

Κύκλος Εργασίας

noun

Το ποσοστό του χρόνου κατά το οποίο ένα σήμα είναι ενεργό (HIGH) μέσα σε μια συγκεκριμένη χρονική περίοδο (κύκλο). Ένας κύκλος εργασίας 100% σημαίνει ότι το σήμα είναι συνεχώς HIGH, ενώ 0% σημαίνει ότι είναι συνεχώς LOW.

Στο Arduino, χρησιμοποιούμε τη συνάρτηση analogWrite(pin, value) για να δημιουργήσουμε ένα σήμα PWM. Παρά το όνομά της, δεν παράγει ένα πραγματικό αναλογικό σήμα. Αντίθετα, ορίζει τον κύκλο εργασίας σε μια από τις ακίδες με δυνατότητα PWM (συνήθως σημειώνονται με μια περισπωμένη ~ δίπλα στον αριθμό τους).

Η τιμή value μπορεί να κυμαίνεται από 0 (0% κύκλος εργασίας, πάντα OFF) έως 255 (100% κύκλος εργασίας, πάντα ON). Μια τιμή 127 θα έδινε έναν κύκλο εργασίας περίπου 50%.

// Ακίδα συνδεδεμένη με το LED
// Πρέπει να είναι μια ακίδα PWM (π.χ. 3, 5, 6, 9, 10, 11 στο Uno)
const int ledPin = 9;

void setup() {
  // Δεν χρειάζεται pinMode() για το analogWrite()
}

void loop() {
  // Αυξάνουμε σταδιακά τη φωτεινότητα
  for (int brightness = 0; brightness <= 255; brightness++) {
    analogWrite(ledPin, brightness);
    delay(10); // Μικρή καθυστέρηση για να φαίνεται η αλλαγή
  }

  // Μειώνουμε σταδιακά τη φωτεινότητα
  for (int brightness = 255; brightness >= 0; brightness--) {
    analogWrite(ledPin, brightness);
    delay(10);
  }
}

Διαβάζοντας τον Αναλογικό Κόσμο

Ενώ ο έλεγχος εξόδων με PWM είναι ισχυρός, συχνά θέλουμε να λαμβάνουμε εισόδους που δεν είναι απλώς ON ή OFF. Σκεφτείτε ένα ποτενσιόμετρο (έναν ρυθμιζόμενο αντιστάτη), έναν αισθητήρα φωτός ή έναν αισθητήρα θερμοκρασίας. Αυτές οι συσκευές παρέχουν μια συνεχώς μεταβαλλόμενη τάση, όχι ένα απλό ψηφιακό σήμα.

Για να διαβάσουμε αυτές τις τιμές, χρησιμοποιούμε τις αναλογικές εισόδους του Arduino (A0, A1, κ.λπ.) και τη συνάρτηση analogRead(pin). Αυτή η συνάρτηση διαβάζει την τάση στην καθορισμένη ακίδα και τη μετατρέπει σε μια ψηφιακή τιμή. Αυτή η διαδικασία εκτελείται από έναν (ADC - Analog to Digital Converter).

Στις περισσότερες πλακέτες Arduino (όπως το Uno), ο ADC έχει ανάλυση 10-bit. Αυτό σημαίνει ότι μπορεί να αναπαραστήσει την τάση εισόδου (συνήθως 0-5V) με $2^{10} = 1024$ διαφορετικές τιμές, από 0 έως 1023.

DigitalValue=AnalogVoltageSystemVoltage×(2Resolution1)DigitalValue = \frac{AnalogVoltage}{SystemVoltage} \times (2^{Resolution} - 1)

Για παράδειγμα, αν η τάση στην ακίδα A0 είναι ακριβώς 2.5V, η συνάρτηση analogRead(A0) θα επέστρεφε μια τιμή γύρω στο 512, που είναι περίπου το μισό του 1023. Αν η τάση είναι 0V, η τιμή θα είναι 0. Αν είναι 5V, η τιμή θα είναι 1023. Αυτό μας επιτρέπει να μετρήσουμε με ακρίβεια τις ενδιάμεσες τιμές.

Lesson image

Κλιμάκωση Τιμών με την map()

Συχνά, το εύρος τιμών που διαβάζουμε από έναν αισθητήρα (π.χ. 0-1023 από το analogRead()) δεν είναι το εύρος που χρειαζόμαστε για μια έξοδο (π.χ. 0-255 για το analogWrite()). Θα μπορούσαμε να κάνουμε τους υπολογισμούς χειροκίνητα, αλλά το Arduino παρέχει μια πολύ βολική συνάρτηση για αυτό: την map().

Η συνάρτηση map(value, fromLow, fromHigh, toLow, toHigh) παίρνει μια τιμή από ένα αρχικό εύρος και την "χαρτογραφεί" σε ένα νέο εύρος.

Φανταστείτε ότι έχετε έναν θερμοστάτη που διαβάζει από 0-1023. Θέλετε να τον αντιστοιχίσετε σε μια ταχύτητα ανεμιστήρα από 0-255. Η map() κάνει ακριβώς αυτό, μετατρέποντας αναλογικά τη μια κλίμακα στην άλλη.

const int potPin = A0;      // Ποτενσιόμετρο στην ακίδα A0
const int ledPin = 9;       // LED στην ακίδα PWM 9

void setup() {
  Serial.begin(9600);
}

void loop() {
  // Διάβασε την τιμή από το ποτενσιόμετρο (0-1023)
  int sensorValue = analogRead(potPin);

  // Κλιμάκωσε την τιμή στο εύρος του PWM (0-255)
  int outputValue = map(sensorValue, 0, 1023, 0, 255);

  // Χρησιμοποίησε την κλιμακωμένη τιμή για να ρυθμίσεις τη φωτεινότητα του LED
  analogWrite(ledPin, outputValue);

  // Εκτύπωσε τις τιμές για να δεις τη μετατροπή
  Serial.print("Sensor = ");
  Serial.print(sensorValue);
  Serial.print("\t Output = ");
  Serial.println(outputValue);

  delay(2);
}

Αυτός ο κώδικας διαβάζει συνεχώς την τιμή από το ποτενσιόμετρο. Στη συνέχεια, η συνάρτηση map() μετατρέπει το εύρος 0-1023 σε ένα νέο εύρος 0-255, το οποίο είναι ιδανικό για να το περάσουμε στη συνάρτηση analogWrite(). Έτσι, καθώς περιστρέφετε το ποτενσιόμετρο, η φωτεινότητα του LED αλλάζει ομαλά.

Ο συνδυασμός analogRead() και analogWrite() (με map()) αποτελεί τη βάση για αμέτρητα διαδραστικά έργα, επιτρέποντας στο Arduino σας να αντιδρά με απόχρωση στον φυσικό κόσμο.