10. Arduino-Projekt: Temperaturmessung mit digitalem IC DS18B20 (15/33)

Der digitale Temperatursensor DS18B20 ist ein IC (Integrated Circuit), das die Temperaturwerte über einen seriellen Datenbus an den Arduino weitergibt. Laut Datenblatt arbeitet der Sensor in einem Temperaturbereich von -55°C bis +125°C.

Durch die serielle digitale Datenleitung kann der Sensor auch über eine relativ lange Leitung (ein Meter und mehr) ohne Messwertverfälschung angeschlossen werden.

Es gibt im Internet verschiedene "vergossene" Varianten mit Verbindungskabel, z. B. hier: https://www.az-delivery.de:

ds18b20
Quelle: https://www.az-delivery.de

Hardware

Die Verdrahtung des Sensors ist sehr einfach:

ds18b20_schaltplan

Für die Funktion wird der Widerstand R1 (Pullup-Widerstand genannt, weil er die Spannung bei fehlendem Signal auf die Versorgungsspannung hochzieht) benötigt, was im Datenblatt so nicht gleich ersichtlich ist.

Hier der Steckbrettaufbau:

ds18b20_steckbrett

Und so eine reale Verdrahtung:

IMG_20191206_163955

Programmierung

Der serielle Datenbus (1-Wire-Bus) und das vom Sensor verwendete Protokoll erfordern erheblichen Programmieraufwand, zum Glück kann die Arduino-IDE um externe Zusatzmodule (Libraries) erweitert werden und für den Sensor gibt es eine solche. Es werden folgende Libraries benötigt:

Die beiden entpackten Verzeichnisse müssen in das Libraries-Verzeichnis der Arduinoinstallation kopiert werden, z. B. nach C:\Program Files (x86)\Arduino\libraries.
 
/**
 * Temperaturmessung mit dem Sensor D18B20
 */

// Die benötigten Libraries werden eingebunden

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

// Definition des Pin, an dem der Sensor hängt

#define SENSOR 9

// Jetzt wird ein OneWire-Instanz mit dem Namen "wire" erzeugt. 
// Das ist eine Variable, die alle Funktionen der Klasse 
// OneWire enthält, wie sie in der OneWire-Library definiert ist. 
// Die Instanz erhält gleich die Pinnumber mitgeteilt an der 
// der Sensor hängt. Das ist die One-Wire-Bus-Verbindung.

OneWire wire(SENSOR);

// Jezt wird eine Instanz der Klasse DallasTemperature
// erzeugt, wie sie in der gleichnamigen Library definiert
// ist. Die Instanz heißt "sensors" und bekommt bei der
// Erzeugung eine Referenz (Zeiger) auf die wire-Variable.
// Dass es sich um eine Referenz handelt, wird durch das
// vorangestellte "&" deutlich gemacht.

DallasTemperature sensors(&wire);

// Die setup()-Funktion

void setup(void)
{
  
  // Serielle Verbindung initialisieren
  
  Serial.begin(9600);

  // Die Library initialisieren
  
  sensors.begin();

}
  

// In der loop()-Funktion werden die Temperaturwerte eingelesen und 
// über die serielle Schnittstelle ausgegeben.

void loop(void)
{
  
  // Die Sensoren am Bus (es sind auch mehrere möglich!) werden
  // angewiesen die Temperaturwerte zu eruieren
  
  sensors.requestTemperatures(); // Send the command to get temperatures

  // Nun werden die Temperaturwerte in Grad Celsius vom ersten (und
  // einzigen) Sensor geholt, der den Index 0 hat.
  
  float temperature = sensors.getTempCByIndex(0);

  // Hier wird geprüft, ob eine sinnvolle Temperatur zurückgegeben
  // wird oder der Wert -127 (der in der DallasTemperature-Library
  // als DEVICE_DISCONNECTED_C definiert ist).
  
  if(temperature != DEVICE_DISCONNECTED_C) {

    // anzeige der Temperatur
    
    Serial.print("Grad Celsius: ");
    Serial.println(temperature);
    
  } else  {

    // Ausgabe einer Fehlermeldung
    
    Serial.println("Error: Die Temperatur kann nicht gelesen werden!");
    
  }
}

 Einige Erläuterungen:

// Die benötigten Libraries werden eingebunden

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

Damit der Arduino-Sketch Zugriff auf die Funktionen der Libraries hat, müssen diese ins Programm eingebunden werden, was diese beiden Anweisungen bewirken.

// Definition des Pin, an dem der Sensor hängt

#define SENSOR 9

Das ist ein Variante zu Definition einer Konstante und wirkt im Wesentlichen wie eine const-Definition.

OneWire wire(SENSOR);

In C++ kann man Objekte definieren, die verschiedene Variablen, Konstanten und Funktionen beinhalten. Wir haben das bei der Klasse "Serial" gesehen. Im Gegensatz zur Serial-Klasse wird bei der OneWire-Klasse aber nicht direkt auf die Funktion in der Klasse zugegriffen, sondern es wird zuerst eine Instanz (Objekt) der Klasse mit dem Namen "wire" definiert. Auf diese Weise könnten auch mehrere unabhängige Instanzen der Klasse "OneWire" definiert werden, z. B. wireOne, wireTwo, was notwendig wäre, wenn mehrere Sensoren am Arduino hingen.

Die Klasseninstanz "wire" erhält die Pinnummer SENSOR (Pin 9) gleich bei der Erzeugung mitgeteilt.

DallasTemperature sensors(&wire);

Genauso ist "sensors" eine Instanz der Klasse "DallasTemperature", die in der gleichnamigen Library definiert ist. Die Instanz "sensors" erhält bei der Erzeugung ebenfalls gleich einen Wert übergeben, der allerdings durch das vorangestellte & etwas Besonderes ist, nämlich eine Referenz oder Zeiger auf eine Klasse. Im speziellen Fall eine Referenz auf die Instanz von "wire".

Referenzen sind nicht die Objekte selber, sondern nur Verweise darauf, ähnlich wie Adressen oder Internet-Links. Die Referenz spart Speicherplatz, da das referenzierte Objekt (hier die Instanz "wire") nur einmal mit allem Drum und Dran im Speicher existiert und die Funktionen der Instanz "sensors" trotzdem darauf zugreifen können.

Kniffliges

1. Modifizieren Sie die Hard- und Software so, dass ein zweiter Sensor desselben Typs angeschlossen werden kann.

2. Kombinieren Sie einen analogen Sensor des Typs TMP36 wie hier beschrieben und vergleichen Sie die Messwerte.

Screenshots wurden mit Fritzing erstellt, falls nicht anders angegeben (https://fritzing.org)

Angerer Harald - Freitag, 6. Dezember 2019

Kategorien: Arduino Tutorials

Kommentieren Sie diesen Beitrag

Ihr Kommentar

Captcha