De Programmeerbare Plantenkas: De Thermistor NTC 10K Temperatuursensor Aansluiten En Programmeren Om De Temperatuur Te Meten

De Programmeerbare Plantenkas: De Thermistor NTC 10K Temperatuursensor Aansluiten En Programmeren Om De Temperatuur Te Meten

SENSOR (CHIP): THERMISTOR - MEETTECHNIEK: THERMISTOR - MEETBEREIK (IN ℃): -55 TOT +125 - PRECISIE (IN ℃): 0,2 - AANSLUITING: ANALOOG

In deze tutorial laten we zien hoe je een NTC 10K thermistor aansluit en programmeert om de temperatuur te meten met een Arduino microcontroller of een andere microcontroller. Deze tutorial hoort bij het artikel "De Programmeerbare Plantenkas: De temperatuur meten met een temperatuursensor", waarin we vertellen hoe je kunt bepalen welke temperatuursensor geschikt is voor jouw project, en waarin we de prestaties van verschillende temperatuursensoren met elkaar vergelijken.

AANSLUITEN

Thermistors zijn in verschillende vormen en maten te koop, van sensoren die waterproof gemaakt zijn en in een metalen omhulsel zitten tot een V-vormig draadje dat alleen door een beetje epoxy in vorm gehouden wordt. In ons voorbeeld werken wij met een kant-en-klare waterbestendige thermistor, zoals de TRU COMPOONENTS thermistor NTC10K, die in een metalen omhulsel zit, omdat dit in de kas makkelijker is om mee te werken. 

Let er op dat niet alle thermistors “negative temperature coefficient”, ofwel NTC, thermistors zijn, en thermistors verschillende weerstanden kunnen hebben. Wanneer je een thermistor met een andere temperature coefficient of een andere weerstand gebruikt, dan moet de aansluiting en de code aangepast worden. Dit voorbeeld werkt dus echt alleen met een NTC 10K thermistor.

thermistor, weerstand
Voor een NTC 10K thermistor gebruiken we een 10K ohm weerstand die te herkennen is aan zijn bruin-zwart-oranje-goud bandjes patroon.
thermistor
De twee kabels van de thermistor hebben geen positieve en negatieve kant, je kunt dus zelf bepalen welke kant je als negatief (aarde) en positief (5 volt en data) gaat gebruiken.

Voor het aansluiten van een NTC 10K thermistor heb je naast de thermistor ook nog een (mini) breadboard, 10K ohm weerstand, te herkennen aan de bandjes in de kleuren bruin-zwart-oranje-goud, en aansluitkabels nodig. Omdat wij werken met een Grove Base Shield hebben wij een aansluitkabel genomen met aan de ene kant mannelijke Dupond stekkers en aan de andere kant een Grove connector.

Om de thermistor aan te sluiten steek je de twee draden van de thermistor eerst elk in een aparte rij van een breadboard. Vervolgens kies je één draad die je gaat gebruiken voor de data en 5 volt aansluiting. In de rij van deze draad steek je een been van de weerstand in. De andere been van de weerstand steek je een paar rijen verderop in een lege rij.

In de rij waarin één draad van de thermistor en één been van de weerstand is gestoken, steek je ook de kabel die je op de analoge pin aansluit. In ons voorbeeld is dit de gele draad die uiteindelijk naar analoge pin A0 gaat.

In de rij waar de andere draad van de thermistor op aan is gesloten, en verder dus nog niets, sluit je de kabel aan die op de aarde (GND) pin van de microcontroller aangesloten wordt. In ons voorbeeld is dit de zwarte draad.

In de rij waar alleen één been van de weerstand zit, steek je de draad die op de 5 volt (5V of VCC) pin van de microcontroller is aangesloten. In ons voorbeeld is dit de rode draad.

thermistor, aanlsuiten
Een NTC 10K thermistor aansluiten op een Arduino UNO met Grove Base Shield.

Programmeren

In dit voorbeeld voor het programmeren van een NTC 10K thermistor hebben we besloten om geen gebruik te maken van een bibliotheek, maar de berekening die nodig is om van het analoge signaal een temperatuur in graden Celsius te maken direct in de code uit te voeren. Op die manier heb je een idee wat er precies gebeurt met de waarde die de microcontroller via de analoge pin binnen krijgt. Er zijn verschillende bibliotheken voor thermistors te vinden in de Arduino IDE, maar vaak is het toch best wel even zoeken hoe en waar je de eigenschappen van de thermistor die je gebruikt moet invoeren.

Doordat we geen gebruik maken van een bibliotheek, moeten we in de voorbereiding van de code een aantal waardes definiëren. De meeste van deze waardes moet je uit de datasheet van de thermistor halen. Voordat je een thermistor koopt, is het daarom te checken dat er een datasheet beschikbaar is voor de specifieke thermistor die je gaat gebruiken.

Het definiëren van de waarde doen we voor elke eigenschap met het commando #define, gevolgd door de naam en de bijbehorende waarde. Aangezien de eigenschappen een vaste waarde hebben, hoeven we geen data type te gebruiken dat wel bedoeld is om van waarde te veranderen, zoals int of float.

Als eerste vertellen we op welke analoge pin de sensor wordt aangesloten, met het commando #define thermistorPin A0. Uiteraard is het zo dat als je de sensor op een andere pin aansluit, dat je de aanduiding A0 moet wijzigen. 

Vervolgens gaan we de eigenschappen van de thermistor definiëren. We vertellen het programma eerst met het commando #define thermistorNominal 10000 welke weerstand de thermistor heeft, bij de specifieke temperatuur die we met het commando #define thermistorTemperatureNominal 25 aangeven. Deze thermistor heeft volgens de datasheet dus een weerstand van 10.000, ofwel 10K, bij een temperatuur van 25 graden Celsius. Deze waardes kunnen verschillen per fabrikant en type thermistor, dus controleer deze waardes goed in de datasheet.

De volgende eigenschap die we definiëren is de B-coëfficiënt van de thermistor. De B-coëfficiënt is een waarde die aangeeft wat de relatie tussen de weerstand die de thermistor biedt en de temperatuur rondom de termistor. Hoe de B-coëfficiënt tot stand komt is een ingewikkeld verhaal, dus daar gaan we hier niet op in. Gelukkig is de B-coëfficiënt gewoon uit de datasheet van de thermistor te halen, en hoef je hier dus zelf geen berekeningen voor te doen.

De laatste eigenschap van de thermistor die we moeten invoeren is welke weerstand we hebben gebruikt om de thermistor aan te sluiten. In ons geval hebben we een 10K weerstand gebruikt, die te herkennen is aan de bruin-zwart-oranje-gouden bandjes. Deze waarde, 10K ofwel 10.000, voeren we in met het commando #define thermistorResistor 10000

Thermistors zijn niet de meest stabiele temperatuursensoren. Daarom gebruiken verderop in de code we niet een enkele waarde die de analoge pin van de thermistor ontvangt, maar het gemiddelde van meerdere waardes om te bepalen wat de temperatuur is. In ons voorbeeld gebruiken we 10 metingen, ofwel samples, om de temperatuur te bepalen. Dit doen we met het commando #define thermistorNrSamples 10. Hoe meer samples je neemt, hoe preciezer de waarde die uit de meting komt. Aan de andere kant, duurt het wel langer om een temperatuur te bepalen naarmate je daar meer metingen voor gebruikt. Welke waarde geschikt is voor jouw project, hangt er dus maar net af of je vooral snel een temperatuur nodig hebt, of vooral een hele precieze temperatuur nodig hebt.

Om de verschillende metingen op te slaan, hebben we een array nodig. Deze maken we met het commando int thermistorMetingen[thermistorNrSamples];. Wat dit commando doet is voor elke keer dat we de temperatuur willen hebben een lijst maken waarin de 10 metingen gezet worden die we gaan gebruiken om tot een gemiddelde meting te komen. 

Als laatste voorbereiding creëren we nog een globale variabele die we thermistorgradenC noemen om de berekende temperatuur als een kommagetal op te slaan. We doen dit met het commando float thermistorgradenC

Om een thermistor te gebruiken, hoeven we niets in de setup fase van het programma te doen. We kunnen dus meteen door met het maken van de functie die we gaan gebruiken om de temperatuur te berekenen op basis van de weerstand die de thermistor ondervind. Om deze makkelijk met andere codes voor andere sensoren en modules te combineren, hebben we er voor gekozen om de commando's die nodig zijn om de temperatuur te bepalen niet in de loop fase van het programma te zetten, maar in een aparte functie die we THERMISTORNTC10K() noemen. Omdat de we temperatuur uiteindelijk als een kommagetal willen opslaan, maken we deze functie aan met het commando float THERMISTORNTC10K(), waarbij float aangeeft dat de functie een kommagetal genereert.

Om uit een thermistor een temperatuur te halen, zijn behoorlijk wat stappen nodig. Allereerst hebben we twee tijdelijke variabele nodig om wat gegevens in op te slaan. Deze maken we aan met de commando's uint8_t thermistori; en float thermistorGemiddelde;

Hierna volgt de eerste echte stap richting het berekenen van de temperatuur. We beginnen namelijk met de array thermistorMetingen, die we in de voorbereiding hebben gemaakt, te vullen met metingen. Dat gebeurd met een for-loop, die we met het commando for (thermistori = 0; thermistori < thermistorNrSamples; thermistori++) {thermistorMetingen[thermistori] = analogRead(thermistorPin);delay(1);} activeren. Wat dit doet, is een lijst maken met tien waardes die uit de analoge pin zijn gehaald. Een voorbeeld van zo'n lijst zou kunnen zijn 500, 500, 501, 502, 499, 500, 499, 501, 499, 500. Om het nemen van de waardes soepel te laten verlopen, laten wij met het commando delay(1) één milliseconden tussen de metingen. 

Als de array is gevuld met de metingen, is het tijd om het gemiddelde van deze metingen te bepalen. Dit doen we ook weer met een for-loop, met het commando for (thermistori = 0; thermistori < thermistorNrSamples; thermistori++) {thermistorGemiddelde += thermistorMetingen[thermistori];}. Wat dit doet is de waardes die in de array thermistorMetingen zijn gezet optellen. 

Zoals je waarschijnlijk wel weet, bereken je een gemiddelde door alle metingen op te tellen, en daarna te delen door het totaal aantal metingen. Dat doen we in deze code ook, met het commando thermistorGemiddelde /= thermistorNrSamples;. Het teken /= is een snelle manier om te zeggen dat de variabele thermistorGemiddelde een nieuwe waarde krijgt, door de waarde die de variabele heeft na het optellen van de individuele metingen te delen wordt door het aantal metingen die we genomen hebben.  

De weerstand die de thermistor aan de stroom die de thermistor binnen komt biedt, wordt bepaald door de temperatuur rondom de thermistor. Om er uiteindelijk achter te komen hoeveel graden Celsius het is, moeten dan ook we eerst berekenen hoeveel weerstand de thermistor biedt. Dit doen we met het commando thermistorWeerstand = thermistorResistor / ((1023 / thermistorGemiddelde) - 1);. Hierbij delen we de waarde van de weerstand die we hebben gebruikt om de thermistor aan te sluiten door 1023 gedeeld door de gemiddelde waarde die we via de analoge pin hebben gemeten, min 1. Het getal 1023 in deze berekening staat voor de maximale waarde die de analoge pin kan meten. Deze waarde is gelijk aan 5 volt. Stel dat de temperatuur van de thermistor boven zijn maximale bereik uit komt, en de thermistor dus geen weerstand meer biedt, dan zou er dus 5 volt de analoge pin binnenkomen en de analoge pin dus een waarde van 1023 aangeven. 

Na het berekenen van de weerstand die de thermistor geeft, kunnen we eindelijk de temperatuur gaan berekenen. Dit doen we met de Steinhart-Hart formule. Deze formule gebruikt de eigenschappen van de thermistor, die we aan het begin van het programma hebben gedefinieerd, om de temperatuur in Kelvin te berekenen. Aangezien wij de temperatuur niet in Kelvin maar in graden Celsius willen hebben, is deze formule nog iets uitgebreidt. Het commando om de Steinhart-Hart formule los te laten op de weerstand die we zojuist berekend hebben is thermistorgradenC = (1.0 / (((log(thermistorWeerstand / thermistorNominal)) / thermistorBCoef) + (1.0 / (thermistorTemperatureNominal + 273.15))) - 273.15);

Om de temperatuurmeting te activeren, geven we in de loop fase van het programma het commando THERMISTORNTC10K();. Op dit moment wordt er nog niets met deze meting gedaan, maar je kunt bijvoorbeeld allerlei leuke modules op de microcontroller aansluiten die aan of uit gaan bij een bepaalde temperatuur. 

ARDUINO IDE CODE


/*
   Voorbeeld code gemaakt door www.foodplanting.com
   voor de Programmeerbare Plantenkas serie.

   Deze code is gemaakt voor een NTC 10K thermistor temperatuursensor.

   Deze code is zeer minimalistisch, omdat het idee is
   dat deze code gecombineerd wordt met codes voor andere
   modules. Zo wordt de temperatuur bijvoorbeeld niet in de
   loop fase, maar in een aparte functie op geroepen en
   wordt de gemeten temperatuur niet in de Serial Monitor
   af geprint.
*/

// Voorbereiding:
#define thermistorPin A0 // Dit geeft aan op welke analoge input de sensor is aangesloten, in dit geval A0.
#define thermistorNominal 10000 // De weerstand die de thermistor biedt bij de onderstaande temperatuur, volgens de datasheet.
#define thermistorTemperatureNominal 25 // De temperatuur die bij de bovenstaande weerstand hoort, volgens de datasheet.
#define thermistorBCoef 3950 // Waarde die aangeeft hoe de niet-lineaire weerstand in relatie staat met de temperatuur, volgens de datasheet.
#define thermistorResistor 10000 // De waarde van de weerstand die gebruikt is bij het aansluiten, in dit geval 10K Ohm.
#define thermistorNrSamples 10 // Het aantal metingen dat gebruikt wordt om een temperatuur te bepalen, hoe meer hoe exacter en langzamer.
int thermistorMetingen[thermistorNrSamples]; // Variabele om de individuele metingen in op te slaan.
float thermistorgradenC; // Dit creëert een globale variabele waarin de gemeten temperatuur wordt opgeslagen.

// Setup fase:
void setup() {
  // Voor deze functie hoeven we niets in de setup fase te doen.
}

// Loop fase:
void loop() {
  THERMISTORNTC10K(); // Vraag de microcontroller om de functie die de temperatuur uit de sensor ophaalt uit te voeren.
}

//Functie voor temperatuursensor:
float THERMISTORNTC10K() {
  uint8_t thermistori; // Een variabele om in bij te houden hoeveel metingen er genomen zijn.
  float thermistorGemiddelde; // Een variabele om het gemiddelde van de metingen tijdelijk in op te slaan.
  float thermistorWeerstand; // Een variabele om de weerstand van de thermistor tijdelijk in op te slaan.

  // Neem het aantal samples dat bij thermistorNrSamples is aangegeven per temperatuur meting.
  for (thermistori = 0; thermistori < thermistorNrSamples; thermistori++) {
    thermistorMetingen[thermistori] = analogRead(thermistorPin);
    delay(1); // Voeg een kleine delay van 1 milliseconde toe om de meting soepeler te laten verlopen.
  }

  // Tel de metingen uit de analoge pin op in variabele thermistorGemiddelde.
  thermistorGemiddelde = 0;
  for (thermistori = 0; thermistori < thermistorNrSamples; thermistori++) {
    thermistorGemiddelde += thermistorMetingen[thermistori];
  }

  // Bereken de weerstand die de thermistor geeft.
  thermistorWeerstand = 0;
  thermistorGemiddelde /= thermistorNrSamples; // Deel de opgetelde waardes van de analoge pin door het aantal samples dat genomen is om de gemiddelde waarde van de analoge pin te bepalen.
  thermistorWeerstand = thermistorResistor / ((1023 / thermistorGemiddelde) - 1); // Deel de waarde van de aangesloten weerstand  door de maximale waarde van de analoge pin gedeeld door de gemeten waarde van de pin, min 1.

  // Bereken de temperatuur in graden Celsius met de Steinhart-Hart formule.
  thermistorgradenC = 0; // Reset de therimstorGradenC variabele.
  thermistorgradenC = (1.0 / (((log(thermistorWeerstand / thermistorNominal)) / thermistorBCoef) + (1.0 / (thermistorTemperatureNominal + 273.15))) - 273.15); // De Steinhart-Hart formule (met Kelvin naar graden Celsius omrekening).
  return thermistorgradenC;
}


Vragen en opmerkingen

We proberen de serie "De Programmeerbare Plantenkas" zo toegankelijk mogelijk te maken voor iedereen. Toch zijn sommige concepten best wel ingewikkeld, omdat er kennis van heel veel verschillende domeinen, zoals natuurkunde, elektrotechniek en computerwetenschappen, samen komen. Het kan daarom best zijn dat we iets niet goed uitgelegd hebben. Mocht er iets niet duidelijk zijn of iets niet zo werken zoals we het in deze tutorial uitgelegd hebben, stuur dan gerust een berichtje via de Disqus op deze pagina. Je kunt de Disqus vinden door naar beneden te scrollen, tot onder de advertenties.