Temperatuur sensoren

Ik onderscheid vier soorten sensoren:
  1. Transistor temperatuursensoren (gewoon of met 1-Wire protocol)
  2. Thermistors ofwel NTC-weerstanden (NTC = Negatieve Temperatuur Coëfficiënt)
  3. IC's ("kaal" of op een breakout board of de TC74 I²C sensor)
  4. Thermokoppels
Thermometers worden ook vaak gecombnineerd met andere sensoren, bijvoorbeeld de DHT11 vochtigheidmeter en de bmpxxx drukmeter.

Transistor

Gewone temperatuurtransistor

Deze thermometers zijn goedkoop (ca 1 euro). Ik testte de TMP36 en de LM35 (LM35DZ). Beide geven een spanning af die lineair is met de temperatuur. De LM35 geeft 10 mV per graad; zijn nauwkeurigheid is ca. 0,6 °C en het meetbereik is van 0 °C tot 100 °C; de TMP36 heeft ook 10 mV per °C, maar geeft 750 mV bij 25 °C het bereik van deze sensor is van -40 °C tot 125 °C. Sluit bij beide sensoren de rechtse pin (als je het opschrift naar voren houdt) aan op GND en de linker pin op VCC (5 V); sluit de middelste poot aan op een analoge ingang, bijvoorbeeld A0. De theoretisch nauwkeurigheid van de sensoren wordt alleen gehaald als de Arduino ook nauwkeurig is en dat is niet altijd het geval. Het beste kun je een voedingsspanning van 9 volt (blokbatterij) nemen, die je aansluit tussen VIN en GND. Een andere mogelijkheid (bij de UNO) is een transformator van 9 volt te gebruiken. De Arduino UNO mag aangesloten blijven op de computer. De analoge ingangen werken tot 5 volt, maar dat heb je bij deze sensoren niet nodig. Je kunt het bereik van de de analoge ingangen verkleinen (en dus een kleiner temperatuurverschil meetbaar maken) door in de setup() functie de instructie analogReference(INTERNAL); op te nemen en dan in de berekening van de temperatuur niet 500 keer te nemen, maar 110 keer. Dit werkt bij de Arduino UNO en verschillende andere Arduino's, maar bij de Arduino Mega moet het iets anders.
Hieronder staan twee programma's die de temperatuur weergeven met beide sensoren. Er is op zich maar één verschil tussen de programma's voor beide types en dat is in de berekening dat bij de TMP36 50,0 moet worden afgetrokken en bij de LM 35 niet. Maar omdat ik het niet zinvol vindt twee vrijwel identieke programma's op te nemen laat ik bij de LM35 zien hoe je de analoge ingang op een kleiner bereik instelt.

Klik hier om de testprogramma's te zien

Er zijn verschillende meer of minder betrouwbare methodes om in de seriële monitor het °C symbool te krijgen.
De regel Serial.print(char(0xC2)); Serial.print(char(0xB0)); Serial.println("C"); schijnt meestal te werken, maar zeker niet altijd!

Transistor met 1-Wire protocol (DS18B20 "Dallas")

De waterdichte uitvoering
Deze transistor werkt heel anders! Hij geeft zijn temperatuur digitaal door via het 1-Wire protocol. Dat lijkt lastig, maar Maxim (het vroegere Dallas Semiconductor) heeft een mooi voorbeeldprogramma online staan. Je kunt de twee benodigde bibliotheken gemakkelijk installeren via het menu "bibliotheken beheren...". Het grote voordeel is dat je met deze transistor niet afhankelijk bent van de referentiespanning van een ADC, waardoor er nauwelijks fouten kunnen ontstaan. ook mag je veel langere draden gebruiken. Je kunt de "kale" transistor gebruiken of de waterdichte versie. In beide gevallen sluit je een 4,7 kΩ weerstand aan tussen VCC en de datapin (een iets andere waarde mag ook wel). Er is ook een versie op een breakout board, waar de weerstand al in zit. Ik testte naast de kale transistor ook de waterdichte versie. Deze sensor is vrij groot en daardoor reageert hij - zeker in lucht - erg traag.
Mijn sensor in een waterkoker...
In een vloeistof is hij een stuk sneller. Door de waterdichte behuizing kun je de thermometer goed controleren door deze in smeltend ijs respectievelijk kokend water te hangen. Mijn sensor blijkt bijzonder weinig af te wijken (minder dan 0,1 °C bij smeltend ijs; minder dan 0,8 °C bij kokend water - zie de grafiek). Ook testte ik een breakout board. Het werkt allemaal prima!

Klik om mijn versie van de sketch te zien  

Het 1-Wire protocol geeft je de mogelijkheid meerdere sensoren uit te lezen, zonder dat je een adres nodig hebt. Gewoon twee sensoren parallel schakelen is genoeg. In het programma neem je voor elke sensor een extra regel Serial.print(sensors.getTempCByIndex(..)); op. In plaats van de puntjes zet je een volgnummer (dus 1, 2 3, enzovoorts). Je moet wel even een van de sensoren warm maken om te zien welke sensor het eerst wordt uitgelezen. Je kunt tientallen sensoren gebruiken, maar als je meer dan vier of vijf gebruikt moet je wel goed nakijken in de Dallas documentatie hoe je de bekabeling het beste kunt doen. Voor de 8 sensoren die je in uitvoer hieronder ziet heb ik de middelste drie regels in de loop() functie vervangen door:
for (byte Sensor = 0; Sensor < 8; Sensor++) {
   Serial.print("Temperatuur bij sensor "); Serial.print(Sensor); Serial.print(": ");
   Serial.print(sensors.getTempCByIndex(Sensor));
   Serial.println(" C");
}

NTC-weerstand (thermistor)

Het nadeel van NTC weerstanden is dat er een ingewikkeld verband is tussen de temperatuur en de weerstand. Daarom moet je altijd met een look-up table (opzoektabel) werken. Deze kun je downloaden bij de fabrikant of leverancier. Nog een nadeel is dat zo'n tabel veel plaats in het geheugen inneemt. Waarom zou je dan zo'n NTC kopen? Als je alleen iets wilt schakelen als een bepaalde temperatuur wordt bereikt dan speelt dit nadeel niet. Een ander voordeel is dat thermistors in vocht- en corrosiebestendige behuizing te verkrijgen zijn. Je kunt ze dan gerust in een vloeistof plaatsen. En tenslotte: ze reageren snel en zijn spotgoedkoop.
Bij de meest gebruikelijke NTC weerstanden moet je een weerstand van 10kΩ aansluiten, waarover je de spanning meet. Deze weerstand komt tussen aarde en een van de ingangen van de NTC (maakt niet uit welke); de andere ingang van de NTC komt aan de voedingsspanning van 5 volt. Als je andere waarden van de voorschakelweerstand en/of de voeding neemt dan klopt de tabel niet meer en meet je dus verkeerde temperaturen.

Thermistor KY-013 op breakout board

Het breakout board, dat je op de foto ziet is handig, omdat je zelf geen weerstand hoeft aan te sluiten en de resultaten zijn daar dus ook niet afhankelijk van. Ik vond op Internet een formule, waarmee je de temperatuur kunt uitrekenen, zodat je geen tabel nodig hebt. Ik heb dit niet goed kunnen testen, maar in het bereik rond de 20 graden Celsius lijken de temperaturen goed te kloppen. Deze thermistor heeft ook een digitale pin. Daarmee kun je een temperatuur instellen waarboven bijvoorbeeld een alarm afgaat. Welke temperatuur dat is, stel je in met de instelweerstand. Je ziet vaak programma's op Internet, waarbij de digitale waarde gelijk met de analoge wordt uitgelezen. Dat vind ik tamelijk zinloos, omdat je met de analoge waarde gemakkelijk een of meerdere alarmniveaus software matig in kunt stellen. Dat kun je dan gewoon in graden doen. Maar als je een serieus alarm nodig hebt, dan is die digitale pin is wèl goed te gebruiken door er een interrupt functie aan te koppelen. Dan zal - ongeacht of je überhaupt de temperatuur meet - alles waar de Arduino mee bezig is worden onderbroken voor het alarm.
Er is ook een kleiner, zwart breakout board, met alleen een digitale pin. Daarbij kun je hetzelfde programma gebruiken.

Klik hier om het testprogramma te zien

IC thermometer DS1620

Meting temperatuur in de diepvrieskast
Een voordeel van IC's is dat ze extra functies hebben, zo heeft dit IC drie uitgangen die een triggerpuls geven als een (instelbare) temperatuur wordt bereikt. Handig om een thermostaat te maken. Een ander voordeel is dat hij een digitale waarde teruggeeft, zodat je niet afhankelijk bent van een ADC (zoals bij transistors) of van tabellen en weerstanden zoals bij de NTC. Een nadeel is dat de chip vrij groot is en dus traag reageert op temperatuursveranderingen. Ik heb alleen de temperatuurmeting getest, niet de triggeruitgangen. Voor zover ik kan nagaan klopt de aangegeven temperatuur bijzonder goed. De waarde verandert in stappen van 0,5 °C; nauwkeuriger kan niet. Het programma werkt voor positieve en negatieve temperaturen. Ik heb negatieve temperaturen getest door de sensor inclusief breadboard en Arduino Uno in mijn vrieskast te leggen en deze via de USB kabel te verbinden met de PC. De temperatuur daalde keurig in ca 20 minuten tot −15,0 °C. Vervolgens heb ik hem getest tot 97 °C. Later mogelijk meer uitleg of een ander programma

Klik hier om het testprogramma te zien

MCP9808 breakout board

Nauwkeurige thermometer; eenvoudig aan te sluiten
Deze kleine sensor heeft dezelfde voordelen als een "kaal" IC, maar is eenvoudiger aan te sluiten. Hij heeft een nauwkeurigheid van ca. 0,3 °C. Het bereik is van -40 °C tot maar liefst +125 °C. Om deze sensor te kunnen gebruiken kun je het best de bijbehorende bibliotheek gebruiken. Met de nieuwste versie van de Arduino IDE is dat erg makkelijk: schets→bibliotheek gebruiken→bibliotheek toevoegen; dan zoeken naar MCP9808; installeren→klaar! Sluit dan VDD aan op VCC en GND op GND, SCK op A5 en SDA op A4 (bij sommige Arduino uitvoeringen gebruik je andere pinnen). Hieronder staat een testprogrammma.
#include "Adafruit_MCP9808.h"

Adafruit_MCP9808 Sensor = Adafruit_MCP9808();

void setup() {
  Serial.begin(9600); // Zet in de volgende regel een ander adres als je het adres hebt veranderd met A0 t/m A2 van de sensor
  if (!Sensor.begin(0x18)) {
    Serial.println("De sensor is niet gevonden. Controleer de aansluitingen en het adres");
    while (1); // Wacht tot de Arduino opnieuw wordt opgestart
  }
}

void loop() {
  Serial.print("Temperatuur: "); Serial.print(Sensor.readTempC(), 1); Serial.print(" "); Serial.print(char(0xC2)); Serial.print(char(0xB0)); Serial.println("C");
  delay(1000);
}
Sensor in de diepvrieskast..
De sensor kun je in de slaapstand zetten met de instructie Sensor.shutdown(); en weer aanzetten met Sensor.wake(); Houd er rekening mee dat de laatste functie een kwart seconde wacht. Als je met lange tussenpozen metingen doet dan is de slaapstand nuttig, want het stroomgebruik zakt dan tot ca. 0,1 microampère.
De sensor gebruikt standaard het adres 0x18, maar dit kun je veranderen door op de adrespinnen A2, A1 en A0 een 0 of een 1 (= VCC) te zetten. Zo kun je maximaal 8 van deze sensoren op een Arduino aansluiten en uitlezen. De pinnen zijn intern met een weerstand verbonden met aarde, zodat je ze niet hoeft aan te sluiten als ze de waarde 0 moeten hebben. Als je wilt weten welk adres je hebt ingesteld, vertaal de binaire waardes op A2, A1 en A0 dan in een getal en tel dat op bij 0x18 (bijvoorbeeld 111 = 7: vul in 0x18 + 7; A0 is de minst belangrijke bit, dus A2,A1,A0 = 011 geeft adres 0x18 + 3). Je zou kunnen uitrekenen welk adres je krijgt, maar dat maakt je programma niet sneller en ook niet korter. In plaats daarvan kun je gewoon initialiseren met (bijvoorbeeld) Sensor.begin( 0x18 + 3 ); zo houd je de programma's overzichtelijk als je meerdere sensoren gebruikt.
De sensor heeft ook nog een zeer geavanceerde alert pin, maar daar is in de bibliotheek helaas geen ondersteuning voor.  Terug naar boven

LM75A breakout board

Aansluitingen v.l.n.r.
VCC, SDA, SCL, OS, GND
LM75(A) temperatuur IC's werken met het I²C protocol. Ze kunnen snel uitgelezen worden. Het bereik is van -55 °C tot 125 °C. Ze geven de temperatuur nauwkeurig weer (op 0,125 °C), maar daar heb je weinig aan omdat de sensor zelf tot 2 °C fout kan zitten. Koop de LM75 altijd als breakout board, zodat je hem makkelijk op een Arduino kunt aansluiten. Via de bibliotheek manager kun je een geschikte bibliotheek vinden (voer in het zoekvenster LM75A in). Nadat je deze geïnstalleerd hebt vind je in het voorbeelden menu twee testprogramma's. De versie die ik testte werkt goed met beide testprogramma's. Deze specifieke uitvoering heeft geen labels bij de pinnen staan, zie bijschrift bij de foto voor de aansluitingen. De pin "OS" (Overtemperature Shutdown) aansluiting hoef je niet te gebruiken. De meeste andere LM75 breakout boards hebben wel labels bij de pinnen staan. Een nadeel van alle breakout boards die ik ken is dat de adrespinnen niet zijn "uitgebroken", waardoor de sensor een vast adres heeft (0x48). Hierdoor kun je maar één LM75A tegelijk gebruiken.

TC74 sensor (TC740A0 t/m TC74A7)
Ook getest met de Wemos mini D1 ESP32

TC74
De TC74 chip
De TC74 gebruikt het I²C protocol om de temperatuur door te geven. Hij is eenvoudig te gebruiken in een Arduino programma. Er zijn 8 varianten, met elk een ander adres. Als je van plan bent tegelijk met de TC74 iets anders op de I2C bus aan te sluiten, zorg dan dat je een uitvoering met een nog vrij adres koopt. Als je alleen de thermometer aansluit dan is dat niet van belang. Je kunt het adres afleiden uit de volledige naam van de sensor: TC74A0 heeft adres 0x48, TC74A1 adres 0x49 en dat loopt op adres 0x4F bij de TC74A7. Alle adressen zijn als commentaar opgenomen in het voorbeeldprogramma verderop. Om de TC74 in een breadboard te kunnen gebruiken moet je de pootjes een beetje buigen. Daarna zit hij er wel mooi stabiel in. De chip is gemonteerd op een metalen plaatje dat je kunt vastschroeven op het object waarvan je de temperatuur wilt weten. Voor het meten van de luchttemperatuur hoeft dat niet. Sluit de TC74 als volgt aan: pootje 3 op GND; pootje 5 op VCC (let op: er zijn 3,3 en 5 volt uitvoeringen); pootje 2 gaat naar SDA (bij de Arduino Uno en vele andere Arduino's is dat pin A4) en pootje 4 naar CLK (bij de Uno is dat pootje A5). Het eerste pootje is niet aangesloten, je kunt daarmee doen wat je wilt (zelfs eraf knippen ;-) ). Het metalen plaatje achter de chip is verbonden met aarde (pootje 3), dus zorg ervoor dat je dit niet kortsluit. Het programma is vrij simpel (zie hieronder). Zorg wel dat je het adres verandert in het adres dat bij jouw uitvoering hoort. De chip heeft veel extra mogelijkheden, zoals een slaapstand waarbij hij heel weinig stroom gebruikt. Als je die functionaliteit nodig hebt download dan van Internet de bibliotheek TC74.h. Als je alleen temperaturen wilt meten heb je die bibliotheek niet nodig. Deze sensor reageert vrij snel op veranderingen van de temperatuur. Het temperatuurbereik is van -45 tot 125 °C; de nauwkeurigheid is ca. 2 graden. Ik heb een sensor met onderstaand programma getest tussen -10 °C (in de diepvries) tot 100 °C (in kokend water). De weergegeven temperaturen leken vrij nauwkeurig.
// Demo programma voor de TC74Ax temperatuur sensor
// Kies het juiste adres:
// TC74A0: 0x48; TC74A1: 0x49; TC74A2: 0x0A; TC74A3: 0x0B;
// TC74A4: 0x0C; TC74A5: 0x0D; TC74A6: 0x0E; TC74A7: 0x0F
#define adres 0x4A // Dit werkt dus alleen met de TC74A2
#include <Wire.h>
void setup() {
  Wire.begin();
  Serial.begin(9600);
}

void loop() {
  Wire.write(0);
  Wire.requestFrom(adres, 1);
  if ( Wire.available() ) {
    int8_t Temperatuur = Wire.read(); // int8_t zorgt ervoor dat temperaturen onder nul automatisch goed gaan
    Serial.print("Temperatuur: "); Serial.print(Temperatuur); Serial.println(" C");
  }
  else Serial.println("Kan de temperatuur niet bepalen. Controleer de aansluitingen.");
  delay(500); // Zet hier het delay dat je nodig hebt
}

Thermokoppel

Thermokoppels zijn vooral goed te gebruiken bij extreme temperaturen. Ik testte een K-type sensor, met een MAX6675 chip. K-type wil zegen dat er chromel en alumel als draden worden gebruikt. Dit is een bekende, goedkope combinatie. De bruikbare range is -270 °C tot maximaal 400 °C, maar helaas ondersteunt de MAX6675 geen negatieve temperaturen. Als je wel negatieve temperaturen wil meten dan zou je de MAX31855 moeten gebruiken, maar die heb ik niet getest. Je kunt de benodigde bibliotheek eenvoudig installeren via de bibliotheek manager van de Arduino. Daar zitten dan meteen enkele voorbeeld programma's bij. Ik vind deze programma's niet zo goed omdat ze een pin gebruiken om de chip van spanning te voorzien. Dat is wel makkelijk bij het aansluiten, maar zorgt er ook voor dat de chip even nodig heeft om te stabiliseren. Hieronder zie je een heel eenvoudig programma om je thermokoppel te testen: Sluit VCC aan op 5 volt en GND op GND (dus niet op een pin), en de pinnen SO op 4, CS op 5 en CLK op 6. Als je andere pinnen wilt gebruiken verander dan de nummers achter #define in de code. Open de Seriële monitor om de temperatuur te zien.
Deze bibliotheek werkt ook met de Wemos D1 mini ESP8266 en de Wemos mini D1 ESP32, maar dan moet je de GPIO nummers invoeren, dus niet D4, D3, D2 maar 2, 0, 4 bij de Wemos D1 mini ESP8266 en 21, 17, 16 bij de Wemos D1 mini ESP32.
#include "max6675.h"
#define SO 4
#define CS 5
#define CLK 6

MAX6675 thermokoppel (CLK, CS, SO);

void setup() {
  Serial.begin(9600);
  Serial.println("Temperatuur volgens het thermokoppel:");
}

void loop() {
  Serial.print("T = "); Serial.print(thermokoppel.readCelsius(), 1);
  Serial.print(" C of ");
  Serial.print(thermokoppel.readFahrenheit(), 1); Serial.println(" F");
  delay(1000);
}

Combinaties

Temperatuur en vochtigheid (DHT11)
Ook getest met de Wemos mini D1 ESP32 met datapin naar D4

DHTDrie uitvoeringen van de DHT11
De DHT11 en DHT22 zijn sensoren die zowel de vochtigheid als de temperatuur meten. Ze zijn wel traag (DHT11: elke twee seconden een meting; DHT22: elke seconde een meting), maar dat is voor de meeste toepassingen geen bezwaar. Er is maar één signaaldraad nodig: deze gaat naar een digitale pin van de Arduino. Omdat de timing vrij tricky is kun je het best de daarvoor bestemde softwarebibliotheek gebruiken. Deze is al aanwezig bij de MicroPython v=distributie. Je hoeft dus niets te installeren. In het voorbeeldprogramma zie je hoe je de temperatuur en de vochtigheid kunt bepalen, maar ook de gevoelstemperatuur uit deze twee. De nauwkeurigheid is niet geweldig: 2 °C voor de temperatuur en 5% voor de vochtigheid. Ook het bereik is niet erg groot: van 0 tot 50 °C, maar er zijn genoeg toepassingen waarbij dat ruim voldoende is. Er zijn ook versies van deze sensor op een bordje met drie pinnen. Voor de software die je gebruiken wil maakt dat niets uit. Zie de foto hiernaast.

Klik hier om het testprogramma te zien

uitvoer
De uitvoer van het voorbeeldprogramma

Temperatuur, druk en hoogte BMP085, BMP180 of BMP280

Deze goedkope sensor is in alle soorten en maten te koop. Hij heeft minimaal vier pinnen, twee voor de voeding en twee voor de I²C interface. Als er meer pinnen zijn dan hoef je die niet te gebruiken. Je kunt de bibliotheek Adafruit_BMP085.h gebruiken. Hiermee lees je gemakkelijk de temperatuur af. Deze is tamelijk betrouwbaar en reageert snel op veranderingen. Het voorbeeldprogramma bij deze bibliotheek laat zien hoe je de druk meet en de hoogte boven zeeniveau, maar die waarde is alleen enigszins betrouwbaar als je de druk op zeeniveau opgeeft. Dat moet je opnieuw doen als de luchtdruk is gewijzigd. De oorspronkelijke BMP085 moet je aansluiten op 3,3 volt, maar bij de nieuwere types kun je alles van 3 tot 5 volt gebruiken. Een andere bibliotheek is SFE_BMP180.h, deze is misschien iets beter, maar de voorbeeldprogramma's die daarbij zitten zijn een stuk ingewikkelder.
Aansluitingen: Arduino Uno: SDA gaat naar pin A4 en SCK gaat naar pin A5.
Bij de Mega2560, Due zijn dit pinnen 20 en 21 en bij de Leonardo 2 en 3.
Een klein programma dat alles doet:
#include <Adafruit_BMP085.h>

Adafruit_BMP085 sensor;

void setup() {
  Serial.begin(9600);
  if (!sensor.begin()) {
    Serial.println("De sensor is niet gevonden. Controleer de aansluiting.");
    while (true); // Wacht tot het programma opnieuw wordt opgestart
  }
}

void loop() {
  Serial.print("Temperatuur: "); Serial.print(sensor.readTemperature()); Serial.println(" graden C");
  Serial.print("Druk = "); Serial.print(sensor.readPressure()); Serial.println(" Pa");
  Serial.print("Hoogte boven zeeniveau: ");
  Serial.print(sensor.readAltitude(101700)); // vul hier de werkelijke druk in (1017 hPa = 101700 Pa)
  Serial.println(" meter");
  Serial.println();
  delay(1000);
}