Das 1-Wire-Protokoll ist kompliziert in der Anwendung und erfordert einen relativ langen Code zum Betrieb der Geräte. Mit Hilfe der DallasTemperature-Bibliothek können wir die Daten des Dallas 1-Wire-Thermometer-ICs einfach abfragen. Von der DallasTemperature-Bibliothek unterstützte Geräte: DS18B20, DS1822, DS18S20, DS1820.
Ein beliebtes Gerät ist beispielsweise der digitale Temperatursensor DS18B20
TO92-Gehäuse, Messbereich zwischen 55°C und +125°C, dies wird in 12-Bit-Auflösung am Datenausgangspin angezeigt.
Es unterstützt eine Betriebsspannung von 3,3 V und 5 V.
Werbung
In diesem Artikel verwenden wir für die Beispiele das DS18B20 1-Wire-Thermometer von Dallas Semiconductor. Der DS18B20 ist ein kleiner Thermometer-IC in einem TO92-Gehäuse, der über einen digitalen Eingang an unser Arduino-Board angeschlossen werden kann. Da es sich um ein 1-Draht-Gerät handelt, benötigt es nur einen digitalen Pin für die Kommunikation mit dem Mikrocontroller.
Installiere die DallasTemperature-Bibliothek
Um die DallasTemperature-Bibliothek zu installieren, öffnen wir den Bibliotheksmanager durch Drücken von ‚Strg+Umschalt+i‘ oder gehen wir zu ‚Sketch -> Bibliothek einbinden -> Bibliotheken verwalten…‘.
Geben wir das Suchfeld „DallasTemperature“ oder „DS18B20“ ein und installieren wir dann die Bibliothek „Miles Burton DallasTemperature„.
Verwendung der Bibliothek DallasTemperature
Um die DallasTemperature-Bibliothek zu verwenden, benötigen wir zunächst die ‚OneWire‘-Bibliothek. Dann können wir die Datei DallasTemperature.h in unserem Sketch aufrufen.
#include <OneWire.h>
#include <DallasTemperature.h>
Um mit dem DS18B20-Sensor zu kommunizieren, erstellen wir zunächst ein oneWire-Objekt und übergeben als Parameter die Nummer des Arduino-Pins, an den die Datenleitung des DS18B20-Sensors angeschlossen ist.
Als Nächstes erstellen wir eine Instanz des DallasTemperature-Objekts, wobei wir einen Verweis auf das soeben erstellte oneWire-Objekt in dessen Parameter einfügen.
const char oneWirePin = 10;
OneWire myOneWire(oneWirePin);
DallasTemperature mySensors(&myOneWire);
DallasTemperature Bibliotheksfunktionen – Inhaltsverzeichnis
Beispiele für die Verwendung der DallasTemperature-Bibliothek – Inhaltsverzeichnis
begin
Zuerst wird der Bus mit der Funktion begin im Abschnitt setup() initialisiert, dann kann die Kommunikation beginnen.
void setup()
{
....
mySensors.begin();
...
}
getDeviceCount
Die Funktion getDeviceCount gibt die Anzahl der auf dem Bus gefundenen Geräte zurück.
int sensors = mySensors.getDeviceCount();
Serial.print("Devices: ");
Serial.println(sensors);
getAddress
Die Funktion getAddress gibt true zurück, wenn sie eine Adresse auf dem Bus an der im Parameter index angegebenen Stelle findet. Die hexadezimale Adresse des gefundenen Geräts wird in den Parameter „deviceAddress“ eingetragen.
DeviceAddress deviceAddress;
int index = 0;
bool foundAddress = mySensors.getAddress(deviceAddress, index);
if(foundAddress)
{
for (int i = 0; i < 8; i++)
{
if (deviceAddress[i] < 0x10) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
validAddress
Die Funktion validAddress gibt true zurück, wenn die Geräteadresse gültig ist.
DeviceAddress deviceAddress;
mySensors.getAddress(deviceAddress, 0);
bool addressIsValid = mySensors.validAddress(deviceAddress);
validFamily
Die Funktion validFamily gibt true zurück, wenn die Adresse zu der von der DallasTemperature-Bibliothek unterstützten Familie von Sensoren gehört.
DeviceAddress deviceAddress;
mySensors.getAddress(deviceAddress, 0);
bool familyIsValid = mySensors.validFamily(deviceAddress);
isConnected
Die Funktion isConnected versucht festzustellen, ob ein Gerät an der im Parameter angegebenen Adresse mit dem Bus verbunden ist.
DeviceAddress deviceAddress;
mySensors.getAddress(deviceAddress, 0);
bool connected = mySensors.isConnected(deviceAddress);
Die Funktion isConnected kann auch mit einem zweiten Parameter versehen werden, der es ihr ermöglicht, das Scratchpad zu lesen.
DeviceAddress deviceAddress;
ScratchPad scratchPad;
mySensors.getAddress(deviceAddress, 0);
bool connected = mySensors.isConnected(deviceAddress, scratchPad);
readScratchPad
Die Funktion readScratchPad liest den Inhalt des Scratchpads des Geräts.
DeviceAddress deviceAddress;
ScratchPad scratchPad;
mySensors.getAddress(deviceAddress, 0);
mySensors.readScratchPad(deviceAddress, scratchPad);
for(int i = 0; i < 9; i++)
{
Serial.print(i);
Serial.print(". byte: ");
Serial.print(scratchPad[i]);
Serial.println();
}
writeScratchPad
Verwenden wir die Funktion writeScratchPad, um den Inhalt des Scratchpads in das Gerät zu schreiben.
DeviceAddress deviceAddress;
ScratchPad scratchPad;
mySensors.getAddress(deviceAddress, 0);
scratchPad[2] = 30;
scratchPad[3] = 18;
mySensors.writeScratchPad(deviceAddress, scratchPad);
readPowerSupply
Die Funktion readPowerSupply gibt true zurück, wenn der parasitäre Modus, also der 2-Draht-Modus, verwendet wird. Gibt „false“ zurück, wenn der normale 3-Draht-Modus verwendet wird.
Wenn keine Geräteadresse angegeben ist, wird geprüft, ob ein Gerät am Bus den Parasitärmodus verwendet.
DeviceAddress deviceAddress;
mySensors.getAddress(deviceAddress, 0);
Serial.println(mySensors.readPowerSupply(deviceAddress));
getResolution
Wenn die Funktion getResolution ohne Parameter aufgerufen wird, gibt sie den allgemeinen Wert der Auflösung für die Geräte am 1-Wire-Bus zurück. Die Auflösung kann 9, 10, 11 oder 12 Bit betragen.
int resolutionGlobal = mySensors.getResolution();
Wenn der Parameter der getResolution-Funktion die Adresse eines bestimmten Geräts ist, gibt sie die Auflösung des angegebenen Geräts zurück.
DeviceAddress deviceAddress;
mySensors.getAddress(deviceAddress, 0);
Serial.print(mySensors.getResolution(deviceAddress), DEC);
setResolution
Der allgemeine Wert der Auflösung für Geräte am 1-Wire-Bus kann auf den im Funktionsparameter setResolution angegebenen Wert eingestellt werden. Die Auflösung kann 9, 10, 11 oder 12 Bit betragen.
mySensors.setResolution(12);
Wird die Funktion setResolution mit zwei Parametern aufgerufen, kann der Auflösungswert für die in Parameter 1 angegebenen Geräte auf den in Parameter 2 angegebenen Wert gesetzt werden.
DeviceAddress deviceAddress;
mySensors.getAddress(deviceAddress, 0);
mySensors.setResolution(deviceAddress, 12);
werbung – amazon.de
setWaitForConversion
Die Funktion setWaitForConversion kann verwendet werden, um ein Flag zu setzen.
Wenn der Parameter der Funktion setWaitForConversion wahr ist, kehrt die Funktion requestTemperature() zurück, wenn die Konvertierung abgeschlossen ist. Dies ist die Standardeinstellung.
Wenn der Parameter der Funktion setWaitForConversion false ist, kehrt die Funktion requestTemperature() sofort zurück. Mit Vorsicht verwenden, die für die Umstellung benötigte Zeit muss eingeplant werden. Diese Methode verhindert nicht, dass das Hauptprogramm während der Konvertierung ausgeführt wird.
#include <OneWire.h>
#include <DallasTemperature.h>
const char oneWirePin = 10;
OneWire myOneWire(oneWirePin);
DallasTemperature mySensors(&myOneWire);
int resolution = 12;
unsigned long lastTemperatureRequest = 0;
int delayForConversion = 0;
float temperature = 0.0;
DeviceAddress deviceAddress;
void setup()
{
Serial.begin(115200);
mySensors.begin();
mySensors.getAddress(deviceAddress, 0);
mySensors.setResolution(deviceAddress, resolution);
mySensors.setWaitForConversion(false);
mySensors.requestTemperatures();
delayForConversion = 750 / (1 << (12 - resolution));
lastTemperatureRequest = millis();
}
void loop()
{
if (millis() - lastTemperatureRequest >= delayForConversion)
{
Serial.print(" Temperature: ");
Serial.println(mySensors.getTempCByIndex(0));
mySensors.requestTemperatures();
lastTemperatureRequest = millis();
}
}
getWaitForConversion
Mit der Funktion getWaitForConversion kann der Wert des von der Funktion setWaitForConversion gesetzten Flags abgefragt werden.
bool waitForConversionFlag = mySensors.getWaitForConversion();
setCheckForConversion
setCheckForConversion legt den Wert des checkForConversion-Flags fest.
Wenn das Flag wahr ist, wartet die Funktion requestTemperature() auf die Antwort vom Thermometer-IC, dass die Konvertierung abgeschlossen ist. Wenn das Flag „false“ ist, wartet die Funktion „requestTemperature()“ eine angegebene Zeitspanne, bis die Konvertierung sicher abgeschlossen ist.
mySensors.setCheckForConversion(false);
getCheckForConversion
Mit der Funktion getCheckForConversion kann der Wert des Flags checkForConversion abgefragt werden.
bool checkForConversionFlag = mySensors.getCheckForConversion();
requestTemperatures
Die Funktion „requestTemperatures“ sendet einen Befehl an alle Geräte am Bus, um eine Temperaturkonvertierung durchzuführen.
mySensors.requestTemperatures();
requestTemperaturesByAddress
Die Funktion „requestTemperaturesByAddress“ sendet einen Befehl an das im Parameter genannte Gerät, um die Temperaturkonvertierung durchzuführen.
DeviceAddress deviceAddress;
mySensors.getAddress(deviceAddress, 0);
mySensors.requestTemperaturesByAddress(deviceAddress);
requestTemperaturesByIndex
Die Funktion „requestTemperaturesByIndex“ sendet einen Befehl an das Gerät mit dem im Parameter angegebenen Index, um die Temperaturkonvertierung durchzuführen.
mySensors.requestTemperaturesByIndex(0);
getTemp
getTemp gibt den Rohtemperaturwert oder DEVICE_DISCONNECTED_RAW zurück, wenn der ScratchPad-Speicher des Geräts nicht erfolgreich gelesen werden kann. Der numerische Wert DEVICE_DISCONNECTED_RAW ist eine große negative Zahl außerhalb des Betriebsbereichs des Geräts.
float tempRaw = mySensors.getTemp(deviceAddress);
getTempC
Die Funktion getTempC gibt die Temperatur in °C oder DEVICE_DISCONNECTED_C zurück, wenn der ScratchPad-Speicher des Geräts nicht erfolgreich gelesen werden kann. Der numerische Wert DEVICE_DISCONNECTED_C ist eine große negative Zahl außerhalb des Betriebsbereichs des Geräts.
float tempC = mySensors.getTempC(deviceAddress);
getTempF
Die Funktion getTempF gibt die Temperatur in °F oder DEVICE_DISCONNECTED_F zurück, wenn der Speicher des ScratchPads nicht erfolgreich gelesen werden kann. Der numerische Wert von DEVICE_DISCONNECTED_F ist eine große negative Zahl außerhalb des Betriebsbereichs des Geräts.
float tempF = mySensors.getTempF(deviceAddress);
getTempCByIndex
Die Funktion getTempCByIndex gibt die Temperatur in °C des Gerätes mit dem im Parameter angegebenen Index zurück.
float tempC = mySensors.getTempCByIndex(0);
getTempFByIndex
Die Funktion getTempFByIndex gibt die Temperatur in °F des Gerätes mit dem im Parameter angegebenen Index zurück.
float tempF = mySensors.getTempFByIndex(0);
werbung
isParasitePowerMode
Die Funktion isParasitePowerMode gibt „true“ zurück, wenn das Gerät am 1-Draht-Bus parasitäre Stromversorgung benötigt.
bool parasiteModeFlag = mySensors.isParasitePowerMode();
isConversionComplete
Die Funktion isConversionComplete gibt true zurück, wenn die Umwandlung auf dem 1-Wire-Gerät abgeschlossen ist. Sie gilt nur für den ersten Sensor am Bus.
setHighAlarmTemp
Mit der Funktion setHighAlarmTemp können wir die Hochalarmtemperatur des Geräts in Celsiusgraden einstellen. Sie akzeptiert den Fließkommawert, ignoriert aber Werte nach dem Dezimalpunkt. Der gültige Bereich ist -55C – 125C.
int celsius = 36;
mySensors.setHighAlarmTemp(deviceAddress, celsius);
setLowAlarmTemp
setLowAlarmTemp-Funktion zum Einstellen der niedrigen Alarmtemperatur des Geräts in Celsius-Graden. Sie akzeptiert den Fließkommawert, ignoriert aber Werte nach dem Dezimalpunkt. Der gültige Bereich ist -55C – 125C.
int celsius = 14;
mySensors.setLowAlarmTemp(deviceAddress, celsius);
getHighAlarmTemp
getHighAlarmTemp gibt die aktuelle Hochalarmtemperatur für das im Parameter angegebene Gerät zurück.
int highAlarmTemp = mySensors.getHighAlarmTemp(deviceAddress);
getLowAlarmTemp
getLowAlarmTemp gibt die aktuelle niedrige Alarmtemperatur für das im Parameter angegebene Gerät zurück.
int lowAlarmTemp = mySensors.getLowAlarmTemp(deviceAddress);
resetAlarmSearch
resetAlarmSearch setzt die von der alarmSearch-Funktion verwendeten internen Variablen zurück.
alarmSearch
alarmSearch sucht nach Geräten mit aktiven Alarmen auf dem 1-Wire-Bus. Wenn es ein Gerät findet, gibt es true zurück und speichert die Adresse des gefundenen Geräts in einer Variablen im Parameter.
DeviceAddress deviceWithAlarmAddress;
bool foundAlarm = mySensors.alarmSearch(deviceWithAlarmAddress);
if(foundAlarm)
{
for (int i = 0; i < 8; i++)
{
if (deviceWithAlarmAddress[i] < 0x10) Serial.print("0");
Serial.print(deviceWithAlarmAddress[i], HEX);
}
}
Serial.println();
hasAlarm
Die Funktion hasAlarm gibt true zurück, wenn ein Gerät einen Alarmzustand auf dem Bus meldet.
bool hasAlarmFlag = mySensors.hasAlarm();
Wenn die Funktion hasAlarm mit der im Parameter übergebenen Geräteadresse aufgerufen wird, gibt sie true zurück, wenn das angegebene Gerät einen Alarm hat.
DeviceAddress deviceAddress;
bool hasAlarmFlag = mySensors.hasAlarm(deviceAddress);
processAlarms
Die Funktion „processAlarms()“ führt den Alarmhandler auf allen von alarmSearch() zurückgegebenen Geräten aus.
mySensors.processAlarms();
setAlarmHandler
Die Funktion setAlarmHandler legt den Alarmhandler fest.
.....
void myAlarmHandler(const uint8_t* deviceAddress)
{
Serial.print(mySensors.getHighAlarmTemp(deviceAddress), DEC);
Serial.println(" °C");
Serial.print(mySensors.getLowAlarmTemp(deviceAddress), DEC);
Serial.println(" °C");
}
....
void setup()
{
.....
mySensors.begin();
mySensors.setHighAlarmTemp(deviceAddress, 32);
mySensors.setLowAlarmTemp(deviceAddress, 16);
mySensors.setAlarmHandler(&myAlarmHandler);
....
}
void loop()
{
.....
mySensors.processAlarms();
......
}
set/get UserData
Wird kein Alarmhandler verwendet, können die beiden Bytes als Nutzdaten verwendet werden.
int data;
DeviceAddress deviceAddress;
mySensors.setUserData(deviceAddress, data);
int data;
int deviceIndex;
mySensors.setUserDataByIndex(deviceIndex, data);
DeviceAddress deviceAddress;
int data = mySensors.getUserData(deviceAddress);
int deviceIndex = 0;
int data = mySensors.getUserDataByIndex(deviceIndex);
toFahrenheit
Die toFahrenheit-Funktion wandelt Celsius in Fahrenheit um.
float celsius = mySensors.getTempC(deviceAddress);
float fahrenheit = mySensors.toFahrenheit(celsius);
toCelsius
Die toCelsius-Funktion konvertiert von Fahrenheit in Celsius.
float fahrenheit = mySensors.getTempF(deviceAddress);
float celsius = mySensors.toCelsius(fahrenheit);
rawToCelsius
rawToCelsius wandelt Rohdaten in Grad Celsius um.
int raw = mySensors.getTemp(deviceAddress);
float celsius = mySensors.rawToCelsius(raw);
rawToFahrenheit
Die Funktion raw To Fahrenheit wandelt Rohdaten in Fahrenheit um.
int raw = mySensors.getTemp(deviceAddress);
float fahrenheit = mySensors.rawToFahrenheit(raw);
celsiusToRaw
Die Funktion celsiusToRaw wandelt Celsius in einen Rohtemperaturwert um.
float celsius = mySensors.getTempC(deviceAddress);
int raw = mySensors.celsiusToRaw(celsius);
Der Arduino Mega 2560 Mikrocontroller-Board
Beispiele für die Verwendung der Bibliothek DallasTemperature
DS18B20 lesen
Im ersten Beispiel wird die Temperatur eines einzelnen DS18B20-Sensors abgefragt und auf den seriellen Monitor geschrieben.
Zu Beginn des Sketches werden wir die notwendigen Bibliotheken aufrufen und eine Instanz von OneWire und DallasTemperature erstellen.
Im Setup-Abschnitt initialisieren wir dann die serielle Schnittstelle und den 1-Wire-Bus mit der Funktion begin.
Die Funktion requestTemperatures wird verwendet, um die Temperaturumrechnung zu starten. Dann wird die Funktion getTempCByIndex verwendet, um die Temperatur in °C vom DS 18B20-Gerät abzurufen.
#include <OneWire.h>
#include <DallasTemperature.h>
const char oneWirePin = 10;
OneWire myOneWire(oneWirePin);
DallasTemperature mySensors(&myOneWire);
void setup()
{
Serial.begin(9600);
mySensors.begin();
}
void loop()
{
mySensors.requestTemperatures();
float tempC = mySensors.getTempCByIndex(0);
Serial.print("Temperature: ");
Serial.print(tempC);
Serial.println("°C");
}
DS18B20-Geräte nach Index lesen
Beim Aufruf der Funktion begin der Bibliothek DallasTemperature wird nach allen unterstützten Sensoren auf dem Bus gesucht. Die auf dem Bus gefundenen Sensoren werden als Array behandelt und jedem Sensor wird ein Index zugewiesen. Dadurch kann jeder Sensor anhand seines Indexes identifiziert werden.
Hier ist ein einfacher Schaltplan, der alle DSB1820 auf dem Bus lokalisiert und dann die Temperatur jedes einzelnen anzeigt.
#include <OneWire.h>
#include <DallasTemperature.h>
const char oneWirePin = 10;
OneWire myOneWire(oneWirePin);
DallasTemperature mySensors(&myOneWire);
int deviceCount = 0;
float tempC;
void setup()
{
Serial.begin(9600);
mySensors.begin();
deviceCount = mySensors.getDeviceCount();
Serial.print(deviceCount, DEC);
Serial.println(" device is on the 1-wire bus.");
}
void loop()
{
mySensors.requestTemperatures();
for (int i = 0; i < deviceCount; i++)
{
Serial.print(i+1);
Serial.print(". Sensor temp.: ");
tempC = mySensors.getTempCByIndex(i);
Serial.print(tempC);
Serial.print("°C -- ");
Serial.print(mySensors.toFahrenheit(tempC));
Serial.println("°F");
}
Serial.println("");
delay(1000);
}
Die Adresse der DS18B20-Thermometer auf dem Bus finden
Alle DS18B20-Thermometer-ICs haben bei der Herstellung eine eindeutige 64-Bit-Adresse erhalten, so dass wir jedes Gerät auf dem 1-Wire-Bus von den anderen unterscheiden können.
Das folgende Schema hilft Ihnen, alle DS18B20-Thermometer am oneWire-Bus zu finden und ihre 1-Wire-Adressen auf dem seriellen Monitor auszugeben. Um die Identifizierung der einzelnen Geräte zu erleichtern, schließen Sie jeweils nur ein DS18B20 IC an den Bus an.
#include <OneWire.h>
#include <DallasTemperature.h>
const char oneWirePin = 10;
OneWire myOneWire(oneWirePin);
DallasTemperature mySensors(&myOneWire);
DeviceAddress newAddress;
int deviceCount = 0;
void setup()
{
Serial.begin(9600);
mySensors.begin();
deviceCount = mySensors.getDeviceCount();
Serial.print(deviceCount, DEC);
Serial.println(" device is on the 1-wire bus.");
Serial.println();
for (int i = 0; i < deviceCount; i++)
{
Serial.print(i+1);
Serial.print(". Sensor Address: ")
mySensors.getAddress(newAddress, i);
printAddress(newAddress);
}
}
void loop() {}
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
Serial.print("0x");
if (deviceAddress[i] < 0x10) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
if (i < 7) Serial.print(", ");
}
Serial.println();
}
Notieren wir alle Adressen auf.
DS18B20 nach Titel lesen
Das folgende Beispiel verwendet die Adressen der DS18B20-Thermometer-ICs zum Auslesen der Temperaturen. Vergessen wirnicht, die Adressen der DS18B20-Sensoren durch die im vorherigen Beispiel extrahierten Adressen zu ersetzen!
#include <OneWire.h>
#include <DallasTemperature.h>
const char oneWirePin = 10;
OneWire myOneWire(oneWirePin);
DallasTemperature mySensors(&myOneWire);
DeviceAddress sensor1 = {0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
DeviceAddress sensor2 = {0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
void setup()
{
Serial.begin(9600);
sensors.begin();
}
void loop()
{
mySensors.requestTemperatures();
Serial.print("1.Sensor temperature: ");
printTemperature(sensor1);
Serial.print("2.Sensor temperature: ");
printTemperature(sensor2);
Serial.println();
delay(1000);
}
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = mySensors.getTempC(deviceAddress);
Serial.print(tempC);
Serial.print("°C -- ");
Serial.print(mySensors.toFahrenheit(tempC));
Serial.println("°F");
}