Θερμόμετρο με το DS18B20 και με τη χρήση του Arduino

Ένας από τους ευκολότερους και φθηνότερους τρόπους μέτρησης της θερμοκρασίας με το Arduino είναι χρησιμοποιώντας τον αισθητήρα DS18B20. Αυτός ο αισθητήρας επικοινωνεί ψηφιακά με τον μικροελεγκτή κάνοντας χρήση της 1-Wire διεπαφής.. Ο DS18B20 κατασκευάζεται από την εταιρεία Dallas Semiconductor Corp. και χρησιμοποιεί ένα μόνο ψηφιακό ακροδέκτη για αμφίδρομη επικοινωνία  με τον μικροελεγκτή.

Ένα βασικό χαρακτηριστικό του αισθητήρα DS18B20 είναι ότι μπορούμε να συνδέσουμε πολλούς αισθητήρες παράλληλα κατανεμημένους σε μια περιοχή. Αυτό το χαρακτηριστικό το επιδεικνύουμε στο τέλος αυτού του οδηγού αφού πρώτα εξετάσουμε πως μετράμε την θερμοκρασία με ένα DS18B20.

Ο αισθητήρας κατασκευάζεται σε δυο τύπους: Ο ένας είναι σε συσκευασία ΤΟ-92 όπως ακριβώς με ένα συνηθισμένο τρανζίστορ. Ο άλλος κατασκευάζεται αδιάβροχα στην άκρη καλωδίου και είναι χρήσιμος όταν μετράμε την θερμοκρασία σε υγρά ή στο υπέδαφος.

Ο θερμοκρασιακός αισθητήρας DS18B20 είναι εξαιρετικά ακριβής και μπορεί να μετρήσει θερμοκρασίες από -55οC έως  +125οC  με ακρίβεια ±0,5οC. Η ανάλυση της ένδειξης μπορεί να οριστεί από τον χρήστη σε 9, 10, 11 ή 12-bits. Η προκαθορισμένη ανάλυση είναι 12-bits (δηλαδή 0,0625 οC). Ο αισθητήρας μπορεί να τροφοδοτηθεί με τάση από 3V έως 5,5V και καταναλώνει μόνο 1mA κατά τη διάρκεια ενεργούς λειτουργίας.

Διάταξη ακροδεκτών του θερμοκρασιακού αισθητήρα DS18B20

Συνδέοντας τον αισθητήρα DS18B20 με το Arduino

Η σύνδεση του DS18B20 με το Arduino είναι απλή. Ξεκινώντας συνδέουμε τον ακροδέκτη VDD με το πιν 5V του Arduino και το GND με το 0V. Έπειτα συνδέουμε το πιν DQ του αισθητήρα με το ψηφιακό πιν του Arduino. Θα χρειαστεί να συνδέσετε μια αντίσταση 4,7ΚΩ pull-up μεταξύ του ακροδέκτη DQ και VDD.

Αν χρησιμοποιείται την αδιάβροχη έκδοση του DS18B20 συνδέστε τον κόκκινο ακροδέκτη στα 5V, τον μαύρο ακροδέκτη στο GND, ενώ ο κίτρινος ακροδέκτης συνδέεται σε ένα ψηφιακό πιν του Arduino. Θα χρειαστεί να συνδέσετε μια 4,7ΚΩ pull-up αντίσταση από τον ακροδέκτη DQ στο VDD.

Εγκαθιστώντας τη βιβλιοθήκη για το DS18B20

Το 1-Wire πρωτόκολλο επικοινωνίας της Dallas Semiconductor είναι κάτι το περίπλοκο και απαιτεί σύνθετο κώδικα για να επιτύχουμε επικοινωνία. Για ξεπεράσουμε αυτή τη δυσκολία πρέπει να εγκαταστήσουμε την βιβλιοθήκη: DallasTemperature.h Έτσι με απλές εντολές μπορούμε να διαβάσουμε την θερμοκρασία από τον αισθητήρα. Επίσης θα πρέπει να εγκαταστήσουμε τη βιβλιοθήκη OneWire που ορίζει πως μεταφέρονται τα δεδομένα πάνω στο δίαυλο 1-Wire μεταξύ του DS18B20 και του μικροελεγκτή (Arduino Nano)

Εγκατάσταση βιβλιοθηκών

Πριν φορτώσεις τον κώδικα στο Arduino θα πρέπει να έχεις εγκαταστήσει δυο βιβλιοθήκες στο περιβάλλον Arduino IDE και συγκεκριμένα τις 1) OneWire που ορίζει τον τρόπο που μεταφέρονται τα δεδομένα στο δίαυλο 1-Wire και την 2) DallasTemperature που αφορά τον τρόπο που δουλύει ο αισθητήρας DS18B20. Ακολούθησε τα παρακάτω βήματα για να τις εγκαταστήσεις.

OneWire
1] Πάτησε εδώ OneWire-2.3.5.zip για να κατεβάσεις την βιβλιοθήκη του πρωτοκόλλου 1-Wire.  Θα πρέπει να έχεις ένα φάκελο .zip στο φάκελο downloads του PC.
2] Κάνε unzip το αρχείο .zip και θα πρέπει να πάρεις τον φάκελο: OneWire.
4] Μετακίνησε τη βιβλιοθήκη OneWire στο φάκελο των βιβλιοθηκών του περιβάλλοντος Arduino IDE.
5] Τέλος κάνε επανεκκίνηση την εφαρμογή Arduino IDE.

DallasTemperature
1]Πάτησε εδώ DallasTemperature-3.9.0.zip για να κατεβάσεις την βιβλιοθήκη της λειτουργίας του αισθητήρα. Θα πρέπει να έχεις ένα φάκελο .zip στο φάκελο downloads του PC
2] Κάνε unzip το αρχείο .zip και θα πρέπει να πάρεις τον φάκελο: DallasTemperature
3]Μετακίνησε τη βιβλιοθήκη DallasTemperature στο φάκελο των βιβλιοθηκών του περιβάλλοντος Arduino IDE.
4] Τέλος κάνε επανεκκίνηση την εφαρμογή Arduino IDE.

Μέτρηση της θερμοκρασίας με ένα DS18B20

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

#include <DallasTemperature.h>
#include <OneWire.h>
#include <LiquidCrystal.h>
// Data wire is plugged into digital pin 8 on the Arduino
#define ONE_WIRE_BUS 8

LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

// Setup a oneWire instance to communicate with any OneWire device
OneWire oneWire(ONE_WIRE_BUS);  

// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);

byte Degree[] = {B00111, B00101, B00111, B00000,
                 B00000, B00000, B00000, B00000
};

void setup(void)
{
  sensors.begin();  // Start up the library
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Temperature:");
  lcd.createChar(0, Degree);   // Δημιουργία συμβόλου
}

void loop(void)
{ 
  lcd.setCursor(0, 1);
  
  // Send the command to get temperatures
  sensors.requestTemperatures(); 

  //print the temperature in Celsius
  lcd.print(sensors.getTempCByIndex(0));
  lcd.write(byte (0))
  lcd.print("C  ");
  
  lcd.setCursor(8, 1);
  //print the temperature in Fahrenheit
  lcd.print((sensors.getTempCByIndex(0) * 9.0) / 5.0 + 32.0);
  lcd.write(byte (0)) 
  lcd.print("F  ");
  delay(500);
 }

Εξήγηση του κώδικα

Ο κώδικας Arduino ξεκινά με την συμπερίληψη των βιβλιοθηκών OneWire.h και DallasTemperature.h Επείσης δηλώνουμε το πιν του Arduino στο οποίο συνδέεται ο ακροδέκτης DQ του αισθητήρα.

#include  <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 8

Μετά δημιουργούμε ένα αντικείμενο oneWire περνώντας στη συνάρτηση δημιουργίας το ψηφιακό πιν του Arduino που συνδέεται ο αισθητήρας (DQ). Αυτό το oneWire αντικείμενο επιτρέπει την επικοινωνία με κάθε one-wire συσκευή και όχι μόνο με το DS18B20. Για επικοινωνία με τον αισθητήρα DS18B20 χρειάζεται να δημιουργήσουμε ένα νέο αντικείμενο της κλάσης DallasTemperature και να περάσουμε στη συνάρτηση δημιουργίας ως παράμετρο την αναφορά του αντικειμένου oneWire που δημιουργήσαμε πριν.

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

Μόλις το αντικείμενο DallasTemperature δημιουργηθεί μπορούμε να ζητήσουμε απλές εντολές για επικοινωνία με τον αισθητήρα:

—Η συνάρτηση begin() αναζητά για συνδεμένους αισθητήρες στο δίαυλο και θέτει την ανάλυση σε 12-bits στον καθένα.
—Η συνάρτηση requestTemperature() δίνει εντολή σε όλους τους αισθητήρες να εκτελέσουν διάβασμα της θερμοκρασίας.
—Η συνάρτηση getTempCByIndex(deviceIndex) διαβάζει και επιστρέφει την θερμοκρασία από τον αισθητήρα. Η παράμετρος deviceIndex είναι η θέση του αισθητήρα στο δίαυλο. (Εάν χρησιμοποιείται ένα μόνο DS18B20 στο δίαυλο, θέτουμε το deviceIndex ίσο με μηδέν.

Άλλες χρήσιμες συναρτήσεις της βιβλιοθήκης DallasTemperature.h

Υπάρχουν μερικές άλλες συναρτήσεις που μπορείς να χρησιμοποιήσεις με ένα αντικείμενο DallasTemperature. Μερικές από αυτές επιδεικνύονται παρακάτω.

—Η συνάρτηση setResolution θέτει την ανάλυση του εσωτερικού μετατροπέα Analog-to-Digital του αισθητήρα DS18B20 σε 9, 10, 11 ή 12-bits οι οποίες αντιστοιχούν σε μεταβολές 0,5οC, 0,25oC, 0,125oC και 0,0625οC αντίστοιχα.
—Η συνάρτηση bool  getWaitForConversion() επιστρέφει τη σημαία waitForConversion. Αυτό είναι χρήσιμο για να ελέγχουμε πότε μια θερμοκρασιακή μέτρηση έχει ολοκληρωθεί.
—Οι συναρτήσεις setHighAlarmTemp()  &   setLowAlarmTemp() θέτουν το πάνω και κάτω όριο κατάστασης συναγερμού σε βαθμούς Κελσίου. Οι έγκυρες τιμές είναι μεταξύ -55 και +125οC
—Η συνάρτηση bool hasAlarm() επιστρέφει true όταν μπαίνει σε κατάσταση συναγερμού με την θερμοκρασία να υπερβαίνει το πάνω ή κάτω όριο θερμοκρασίας.

Διαβάζοντας τις θερμοκρασίες από πολλαπλά DS18B20

Ένα από τα πλεονεκτήματα του αισθητήρα DS18B20 είναι ότι πολλαπλά DS18B20 μπορούν να συνυπάρχουν στον ίδιο 1-Wire δίαυλο με καθένα DS18B20 να έχει το δικό του 64-bit σειριακό κωδικό από την γραμμή παραγωγής και με αυτό τον τρόπο διαχωρίζεται ο ένας από τον άλλο. Αυτό το χαρακτηριστικό προσφέρει μεγάλο πλεονέκτημα όταν θέλουμε να ελέγξουμε πολλά DS18B20 κατανεμημένα σε μια μεγάλη περιοχή.

Για να μπορέσουμε να διαβάσουμε τις θερμοκρασίες από πολλαπλά DS18B20 τα συνδέουμε παράλληλα, δηλαδή όλους τους ακροδέκτες VDD μαζί, τους ακροδέκτες GND μαζί και τους DQ μαζί. Στη συνέχεια συνδέουμε τους ακροδέκτες VDD σε τάση 5V πάνω στο Arduino, τους GNDs στα 0V στο Arduino και τους DQ σε ένα ψηφιακό πίν του Arduino. Στη συνέχεια θα πρέπει να συνδέσουμε μια αντίσταση pull-up 4,7ΚΩ μεταξύ των ακροδεκτών DQ και VDD.

Επειδή το πρωτόκολλο 1-Wire είναι κάτι το σύνθετο, θα χρειαστεί να χρησιμοποιήσουμε τις ίδιες βιβλιοθήκες. Αν δεν τις έχετε εγκαταστήσει κοιτάξτε πως τις εγκαταστήσαμε παραπάνω.

Αφού συναρμολογήσουμε το κύκλωμα ανεβάζουμε τον ακόλουθο κώδικα στο Arduino Nano

#include <LiquidCrystal.h> 
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // Δημιουργία αντικειμένου lcd

#include <OneWire.h>
#include <DallasTemperature.h>

// Ο δίαυλος δεδομένων είναι συνδεμένος με το ψηφιακό πιν 8 του Arduino
#define ONE_WIRE_BUS 8

// Δημιουργία ενός αντικειμένου oneWire για επικοινωνία με άλλες OneWire συσκευές
OneWire oneWire(ONE_WIRE_BUS);  

// Πέρασμα μιας αναφοράς oneWire πάνω στο DallasTemperature library
DallasTemperature sensors(&oneWire);

byte Degree[] = { B00111, B00101, B00111, B00000,
                  B00000, B00000, B00000, B00000
};
int deviceCount = 0;
int tempC;

void setup(void)
{
  sensors.begin();  // Αρχικοποίηση του DS18B20
  lcd.begin(16, 2); // Αρχικοποίηση του LCD
  lcd.createChar(0, Degree);   // Δημιουργία συμβόλου
  
  lcd.setCursor(0, 0);
  lcd.print("Locating devices...");
  lcd.setCursor(0, 1);
  lcd.print("Found ");
  deviceCount = sensors.getDeviceCount();
  if (deviceCount >3) deviceCount = 3;
  lcd.print(deviceCount, DEC);
  lcd.print(" devices.");
  //Serial.println("");
  delay(3000);
  lcd.setCursor(0, 0);
  lcd.print("T1:   T2:    T3:");
}

void loop(void)
{ 
  // Εντολή προς όλους τους αισθητήρες για μέτρηση της θερμοκρασίας
  sensors.requestTemperatures(); 
  lcd.setCursor(0, 1);
  // Εμφάνιση θερμοκρασίας από κάθε αισθητήρα
  for (int i = 0;  i < deviceCount;  i++)
  {
    tempC = sensors.getTempCByIndex(i);
    lcd.print((byte)tempC);
    if(i < 2) {lcd.write(byte (0)); lcd.print("C  ");}
    if(i==2) {lcd.write(byte (0)); lcd.print("C"); }
   }
  delay(1000);
}

Σε αυτό τον κώδικα καθώς η βιβλιοθήκη DallasTemperature αρχικοποιείται, ανιχνεύονται όλοι οι αισθητήρες που βρίσκονται πάνω στον ίδιο δίαυλο 1-Wire. Με αυτόν τον τρόπο ορίζονται όλοι οι αισθητήρες DS18B20 πάνω στον δίαυλο σαν ένα πίνακα αισθητήρων και σε καθένα εκχωρεί και από ένα δείκτη. Έτσι μπορούμε να ξεχωρίζουμε κάθε αισθητήρα από το δείκτη του και έτσι καταφέρνουμε να διαβάζουμε την θερμοκρασία από αυτόν.

Εξήγηση του κώδικα

—Ο κώδικας αρχίζει με την συμπερίληψη των βιβλιοθηκών και δηλώνεται το πιν του Arduino πάνω στο οποίο συνδέονται οι ακροδέκτες DQ των αισθητήρων και στη συνέχεια δημιουργείται ένα αντικείμενο βιβλιοθήκης DallasTemperature.

—Στο σώμα της συνάρτησης setup() καλούμε πρώτα την συνάρτηση begin(). Αυτή αρχικοποιεί το δίαυλο και ανιχνεύει όλους τους αισθητήρες που βρίσκονται πάνω στο δίαυλο. Σε κάθε αισθητήρα αντιστοιχίζεται ένας δείκτης και η ανάλυση τίθεται σε 12-bit.

—Μετά καλούμε την συνάρτηση getDeviceCount() για να πάρουμε τον αριθμό των αισθητήρων που βρίσκονται πάνω στο δίαυλο.

—Μέσα στη συνάρτηση βρόγχου loop() καλούμε την συνάρτηση requestTemperatures() για να δώσουμε εντολή σε όλους τους αισθητήρες να μετρήσουν τη θερμοκρασία.

—Στο βρόγχο επανάληψης  for(int i=0; i<deviceCount; i++) κινούμαστε πάνω στο πίνακα των αισθητήρων για να διαβάσουμε την θερμοκρασία από τον αισθητήρα με δείκτη i, απλά καλώντας τη συνάρτηση getTempCByIndex(i);