Project: Temperatuur meten met Arduino en de DS18B20 sensor

Voor het meten van temperatuur zijn veel sensoren beschikbaar, maar eentje springt naar voren als het gaat om de beste prijs/kwaliteit verhouding en dat is de DS18B20 temperatuursensor. Een lage prijs, hoge nauwkeurigheid en breed bereik: wat wil je nog meer? Leer in deze tutorial hoe je met een Arduino de DS18B20 digitale temperatuursensor via de 1-wire bus kunt uitlezen.

Wat heb je nodig om de temperatuur met een Arduino uit te lezen?

In deze tutorial maken we gebruik van hardware om de schakeling op te bouwen, en ook software voor het aansturen en uitlezen van de temperatuursensor. Helemaal onderaan de pagina zie je de producten die je bij ons kunt kopen om gelijk aan de slag te gaan.

Hardware

Software

Specificaties van de DS18B20 temperatuursensor

De DS18B20 is een digitale temperatuur sensor van Dallas Semiconductor Corp en heeft een temperatuurbereik van -55°C tot maar liefst +125°C. Met een nauwkeurigheid van ±0.5°C over dit bereik is dit een erg precieze sensor. Daarbij kun je de temperatuur uitlezen met een 12-bit resolutie, wat betekend dat je temperatuurverschillen tot 0.0625°C kunt detecteren. De uitvoering die wij aanbieden is ook nog een waterdicht, dus temperatuurmetingen voor vloeistoffen behoort ook tot de mogelijkheden.

Het communiceren met de sensor gaat via de 1-wire bus, een unieke interface waarmee je data via slechts één datalijn kunt versturen en ontvangen. Daarbij komt ook nog dat je meerdere sensoren, tot wel 20 stuks, op dezelfde 1-wire bus kunt aansluiten.

Resolutie en conversietijd DS18B20 sensor

Er is echter wel een afweging bij een hoge resolutie, en dat is de conversietijd. Een hogere resolutie is direct gerelateerd aan een langere conversietijd. Dat is de tijd die de sensor nodig heeft voor het meten van de temperatuur.

Bij de maximale resolutie van 12 bits zul je maximaal 750 ms moeten wachten voordat de waarde uitgelezen kan worden. Omgerekend kun je dan temperatuurverschillen van 0.0625°C detecteren. Wil je sneller de temperatuur uitlezen? Dan zul je de resolutie moeten verlagen. Ga je bijvoorbeeld naar 10 bits resolutie, dan kun je elke 188 ms een temperatuur uitlezen. Het maximale temperatuurverschil dat met 10 bit resolutie gedetecteerd kan worden is 0.25°C.

Afhankelijk van de toepassing kies je dus voor de resolutie die het beste bij jouw project past.

In de tabel hieronder zie je de conversietijden van verschillende resoluties.

Resolutie (bits)Resolutie (C)Conversietijd
9 bit0.50°C< 94 ms
10 bit0.25°C< 188 ms
11 bit0.125°C< 375 ms
12 bit0.0625°C< 750 ms


DS18B20 temperatuursensor aansluiten op een Arduino

Het aansluiten van de DS18B20 temperatuursensor is extreem eenvoudig. Uit de sensor komen drie draden die je als volgt aansluit:

  • VCC: De rode draad gaat naar +5V
  • GND: De zwarte draad naar de GND
  • Data: De gele draad naar een digitale IO, en voorzien van een 4.7K Ohm pull-up weerstand

Wij zetten in deze tutorial de datalijn op pin 2 van de Arduino. Ook zetten we een weerstand van 4.7K Ohm parallel tussen de datalijn en de VCC, aangezien dit een vereiste is om via de 1-wire bus te communiceren.

Arduino software voor het uitlezen van de DS18B20 temperatuursensor

Nadat je de sensor volgens bovenstaande schema hebt aangesloten op de Arduino kun je beginnen met het schrijven van de software. In de code wordt er gebruik gemaakt van een externe library genaamd 'DallasTemperature', die kun je hier downloaden:

Download Arduino Library <DallasTemperature.h>

Installeer de Library in Arduino, en dan kunnen we beginnen met het schrijven van de code.

Begin met het toevoegen van de twee Libraries OneWire.h en DallasTemperature.h, en geef aan op welke pin je de 1-wire datalijn hebt aangesloten. In ons geval is dat pin 2.

Daarna maak je een OneWire object aan, en geeft als parameter de pin mee waarop de datalijn is aangesloten. Met dit object kun je ook andere 1-wire sensoren uitlezen, en je bent dus niet beperkt tot enkel de DS18B20 temperatuursensor.

Om het communiceren met de DS18B20 wat te vereenvoudigen maken we gebruik van de DallasTemperature Library. Hierin staan enkele handige functies die je kunt aanroepen, zoals bijvoorbeeld requestTemperatures() om alle temperatuursensoren (van Dallas Semicondutor Corp) op de 1-wire bus uit te lezen. We maken dus een variable genaamd sensors aan, van het type DallasTemperature, en geven het oneWire object als referentie mee.

// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2 // 1-Wire bus data pin

// Setup a oneWire instance to communicate with any OneWire devices
// This is not limited to only the DS18B20
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

Vervolgens kunnen de in de setup() de seriële poort en de sensors variabele initialiseren. De seriële poort gaan we gebruiken om data weer te geven in de Serial Plotter die in de Arduino IDE zit. Ook zetten we hier de resolutie van de sensor op 12 bits. Het bereik van de resolutie is 9 tot 12 bits, waarbij 12 het nauwkeurigste is.

Om alle aangesloten sensoren in kaart te brengen roepen we de sensors.begin() aan. Met deze functie geef je de Arduino instructies om alle aangesloten sensoren actief te gaan zoeken, en op te slaan in de sensors variabele. Dit is noodzakelijk om straks per sensor de temperatuur uit te kunnen lezen, of een andere functie aan te roepen om een specifieke sensor uit te lezen. De sensoren worden via een zogenaamde index aangeroepen, waarbij de eerste gevonden sensor een indexnummer van 0 heeft.

void setup(void){
  // start serial port
  Serial.begin(9600);

  // Start up the DallasTemperature library
  sensors.begin();

  // Set up the resolution for our sensors
  sensors.setResolution(12);
}

Daarna kunnen we in de loop() de DS18B20 sensor uitlezen.

We beginnen met het aanroepen van de functie requestTemperatures() op de sensors variabele. Hiermee sturen we een commando naar alle aangesloten sensoren op de 1-wire bus om een temperatuurmeting te starten.

De tijd die het kost om de meting uit te voeren is afhankelijk van de resolutie die is ingesteld. In de setup() is de resolutie gezet op 12-bits (maximaal), en daarbij is de conversietijd maximaal 750ms. Wil je de sensor sneller uitlezen? Dan zul je resolutie moeten inleveren. Bij een resolutie van 9 bits duurt het maximaal 94ms voordat je de temperatuur kunt uitlezen.

Zodra de conversie is voltooid zal het programma automatisch verder springen naar de volgende regel code waar we een instructie uitvoeren om de temperatuur van een bepaalde sensor uit te lezen. Met de functie getTempCByIndex(0) geven we instructies om de temperatuur in graden Celsius van de eerste sensor (index 0) te ontvangen.

void loop(void){ 
  sensors.requestTemperatures(); // Send the command to start the temperature conversion

  // After we got the temperatures, we can print them here.
  // We use the function ByIndex, and as an example get the temperature from the first sensor only.
  float tempC = sensors.getTempCByIndex(0);

  // Check if reading was successful
  if(tempC != DEVICE_DISCONNECTED_C) {
    Serial.println(tempC); // Print temperature of device 1 (index 0)
  }else{
    Serial.println("Error: Could not read temperature data");
  }
}

Dit is de volledige, en meest eenvoudige code, om de temperatuur van 1 sensor uit te lezen. Als we dit gaan plotten in de Serial Plotter van de Arduino IDE ziet dat er als volgt uit:

Handige functies van de DallasTemperature.h Library

Om zo goed mogelijk gebruik te maken van de DallasTemperature Library zijn hieronder enkele handige functies te vinden die van toepassing kunnen zijn voor jouw project. Een overzicht van alle functies kun je vinden in het .h-bestand van deze Library.

  • getDS18Count() - Het aantal gevonden DS18-sensoren zoals de DS18B20. Erg handig als je via een loop meerdere sensoren wilt uitlezen via de getTempCByIndex(n) functie.
  • setResolution() - Stel makkelijk de resolutie in van de temperatuursensoren. Kies uit 9, 10, 11 of 12 bit. Voorbeeld: sensors.setResolution(10).
  • setHighAlarmTemp() & setLowAlarmTemp() - Stel een alarm in als een waarde boven of onder een bepaalde grens komt. Let op: je moet beide functies aanroepen, anders wordt het alarm niet meer gereset. Je kunt dus niet alleen maar een hoog óf laag temperatuur alarm instellen.
  • hasAlarm() - Controleer eenvoudig of er op een specifieke sensor een alarm geactiveerd is.

Device adres uitlezen
Voor sommige functies moet je het 64-bits adres van de sensor doorgeven als referentie, en dit is niet gelijk aan het index-nummer dat bij sommige functies gebruikt wordt. Om het 64-bits adres uit te lezen kun je onderstaande code gebruiken.

DeviceAddress deviceAddress
sensors.getAddress(deviceAddress, 0);

Maak eerst een variabele van het type DeviceAddress aan. Hierin wordt het 64-bits adres opgeslagen.

Zorg er daarna voor dat je de sensors initialiseerd met de functie sensors.begin(). Deze functie zoekt actief naar alle sensoren op de 1-wire bus en slaat deze op in de sensors variabele. Deze functie moet je uitvoeren vóórdat je het 64-bits adres van een sensor wilt uitlezen, liefst in de setup() van de software. Logisch, want anders zou je niet weten van welke sensor je het adres opvraagt.

Daarna kun je de functie sensors.getAddress( &deviceAddress, index ) aanroepen. Deze functie zet het 64-bits adres van een bepaalde index (bijvoorbeeld 0) in de deviceAddress variabele. Deze variabele kun je dan gebruiken binnen de Library om functies zoals onderstaand aan te roepen:

sensors.setHighAlarmTemp(deviceAddress, 45); // Set High Temperature alarm at 45 degrees Celsius
sensors.setLowAlarmTemp(deviceAddress, -10); // Set Low Temperature alarm at -10 degrees Celsius

if(sensors.hasAlarm(deviceAddress)){
  // .. Do something important
} 

Bouw je eigen Temperatuur monitoringssysteem met Arduino

Verder lezen

Deel deze handleiding