DE PROGRAMMEERBARE PLANTENKAS / TEMPERATUURSENSOREN / EEN MCP9700 TEMPERATUURSENSOR AANSLUITEN EN PROGRAMMEREN OM DE TEMPERATUUR TE METEN
SENSOR (CHIP): MCP9700 - MEETTECHNIEK: LINEAR THERMISTOR - MEETBEREIK (IN ℃): -40 TOT +150 - PRECISIE (IN ℃): 4 - AANSLUITING: ANALOOG
In deze tutorial laten we zien hoe je een MCP9700 temperatuursensor 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
Het aansluiten van de MCP9700 temperatuursensor gaat zeer eenvoudig. De sensor heeft een bolle en een platte kant. Wanneer de platte kant naar je toe gericht is, dan zet je op het linkerbeen van de sensor de 5 volt aansluiting, op het middelste been de analoge pin aansluiting en op het rechterbeen de aarde aansluiting. Om het aansluiten makkelijk te maken kun je de sensor op een (mini) breadboard zetten.
Programmeren
Een lineaire thermistor is eenvoudig te programmeren zonder een bibliotheek. Dat komt, omdat de thermistor zo is gemaakt dat de hoeveelheid volt die de analoge pin binnenkomt met een vaste hoeveelheid omhoog gaat per graden Celsius. In het geval van de MCP9700 komt er voor elke graden Celsius 10 millivolt, ofwel 0,01 volt, de analoge pin binnen. Gebruik je een andere lineaire thermistor, dan kan het zijn dat er per graden Celsius meer of minder volt wordt doorgegeven, dus het is altijd aan te raden om eerst de datasheet te controleren voordat je aan de slag gaat.
Aangezien we geen gebruik maken van een bibliotheek, moeten we zelf eerst wat waardes definiëren in de code. Als eerste vertellen we de microcontroller op welke analoge pin de sensor zit
aangesloten. Dit doen we met het commando #define MCP9700Pin A0
. Vervolgens moeten we twee gegevens over de sensor, die we uit de datasheet gehaald hebben opslaan. De hoeveelheid
volt, in millivolt, die altijd de analoge pin binnenkomt als de sensor goed is aangesloten definiëren we met het commando #define MCP9700utputVolt 500
. Bij deze sensor komt er dus
altijd 500 millivolt binnen, ongeacht wat de temperatuur is. Het volgende commando, #define MCP9700TempCoef 10
verteld hoeveel millivolt er per graden Celsius bij komt, in dit geval
dus 10 millivolt.
We willen graag dat de temperatuur die uiteindelijk uit ons programma komt een goede weergave is van de werkelijke temperatuur. We weten dat de temperatuursensor een bepaalde foutmarge heeft. In
het geval van de MCP9700 is de foutmarge zelfs 4 graden Celsius. Dit betekent dus dat wanneer de sensor aangeeft dat het 10 graden is, dat de werkelijke temperatuur tussen de 6 en 14 graden
Celsius kan liggen. Om zo min mogelijk last te hebben van de foutmarge, nemen we het gemiddelde van een aantal metingen om een gemiddelde temperatuur te bepalen. Hiervoor moeten we in de
voorbereiding aangeven op basis van hoeveel metingen we een temperatuur willen bepalen. Dit doen we met het commando #define MCP9700NrSamples 10
. In dit voorbeeld gebruiken we dus
tien samples om de temperatuur te bepalen. Algemeen geldt dat hoe meer samples je hebt, hoe preciezer de meting is, maar hoe langzamer het programma wordt. Om al deze samples later op te slaan,
moeten we ook nog een variabele maken waarin we de verschillende waardes in kunnen opslaan. Dit doen we met het commando int MCP9700Metingen[MCP9700NrSamples];
. Dit zorgt er dus voor
dat we een lijstje hebben, die MCP9700Metingen
heet, waarin we net zoveel metingen in kunnen zetten als MCP9700NrSamples
groot is. In dit voorbeeld zal
MCP9700Metingen
dus tien metingen gaan bevatten.
Als laatste voorbereiding geven we nog het commando float MCP9700gradenC;
. Dit maakt een variabele aan waarin we de temperatuur als een kommagetal kunnen opslaan.
In deze code hoeven we niets in de setup fase te doen, dus kunnen we meteen verder naar het creëren van een functie die de temperatuur gaat berekenen. Je zou dit ook direct in de loop fase van
het programma kunnen doen, maar dan wordt de code snel rommelig als je andere stukjes code voor andere sensoren en modules gaat toevoegen. Om de functie te maken beginnen we met het commando
float MCP9700()
. Wat er daarna tussen de {} staat wordt uitgevoerd zodra de functie wordt geactiveerd.
In onze functie maken we eerst twee variabele aan, die alleen door deze functie gebruikt worden. De eerste variabele maken we aan met het commando uint8_t MCP9700i;
en zal door het
programma gebruikt worden om te tellen. Daarna gebruiken we het commando float MCP9700GemVolt;
om een variabele aan te maken die het gemiddelde van de verschillende metingen die we
gebruiken om de temperatuur te bepalen opslaat.
De volgende stap in de functie is MCP9700Metingen
met MCP9700NrSamples
te vullen. In ons voorbeeld worden er dus tien metingen in de variabele
MCP9700Metingen
opgeslagen. Dit doen we met het commando for (MCP9700i = 0; MCP9700i < MCP9700NrSamples; MCP9700i++) {MCP9700Metingen[MCP9700i] = analogRead(MCP9700Pin) *
(5000.0 / 1023);delay(1);}
We gebruiken dus een for-loop om in dit geval 10 metingen te nemen, en deze één voor één in de variabele MCP9700Metingen
te zetten.
Het commando MCP9700Metingen[MCP9700i] = analogRead(MCP9700Pin) * (5000.0 / 1023)
in de for-loop haalt hierbij de waardes op uit de analoge pin. Hierbij laten we de
microcontroller dus de analoge pin waarop de MCP9700 temperatuursensor is aangesloten uitlezen, en vermenigvuldigen we die waarde vervolgens met 5000 gedeeld door 1023. De 5000 staat hier voor
5.000 millivolt, ofwel 5 volt. De analoge pin zet het aantal volt dat de microcontroller binnen komt om in een cijfer tussen de 0 en 1023, waarbij 0 betekent dat er geen volt binnenkomt, en 1023
betekent dat het maximale aantal van 5 volt binnen komt. Door 5000 te delen door 1023 weten we dus dat er per millivolt die de pin binnen komt, er een waarde van ongeveer 4,89 bij komt. Door de
waarde die de analoge pin aangeeft te delen door 5000/1023 weten we dus hoeveel millivolt er binnen is gekomen.
Om van de lijst van metingen een gemiddelde te halen, moeten we de waardes eerst op tellen. Dit doen we ook weer met een for-loop, met het commando for (MCP9700i = 0; MCP9700i <
MCP9700NrSamples; MCP9700i++) {MCP9700GemVolt += MCP9700Metingen[MCP9700i];}
. Bij de variabele MCP9700GemVolt
worden dus de tien waardes in MCP9700Metingen
op
geteld, door het teken += te gebruiken. Om het gemiddelde te berekenen moeten we de verschillende waardes op tellen en daarna delen door het totaal aantal metingen. Dit delen doen we met het
commando MCP9700GemVolt /= MCP9700NrSamples;
dat na de for-loop komt.
Als we eenmaal het gemiddeld aantal volt weten, dan kan onze functie gaan bepalen wat de temperatuur in graden Celsius is. Dit wordt gedaan met het commando MCP9700gradenC = (MCP9700GemVolt
- MCP9700utputVolt) / MCP9700TempCoef;
. Hierbij wordt eerst het aantal millivolt af getrokken dat altijd naar de analoge pin wordt gestuurd, ongeacht hoe warm of hoe koud het is. In ons
voorbeeld is dit 500 millivolt. Dit wordt vervolgens gedeeld door de temperatuur coëfficiënt, in dit geval 10, om het aantal binnengekomen volt om te zetten naar graden Celsius.
Om de functie te activeren moeten we in de loop fase van het programma het commando MCP9700();
geven. Op dit moment wordt er niets met deze temperatuur gedaan, maar je kunt
bijvoorbeeld een waaier aan zetten als de temperatuur te hoog wordt.
Arduino IDE Code
/* Voorbeeld code gemaakt door www.foodplanting.com voor de Programmeerbare Plantenkas serie. Deze code is gemaakt voor een MCP9700 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 MCP9700Pin A0 // Dit geeft aan op welke analoge input de sensor is aangesloten, in dit geval A0. #define MCP9700utputVolt 500 // Hoeveelheid millivolt die de sensor altijd de analoge pin in brengt. #define MCP9700TempCoef 10 // Hoeveelheid millivolt die de sensor per graden Celsius de analoge pin in brengt. #define MCP9700NrSamples 10 // Het aantal metingen dat gebruikt wordt om een temperatuur te bepalen, hoe meer hoe exacter en langzamer. int MCP9700Metingen[MCP9700NrSamples]; // Variabele om de individuele metingen in op te slaan. float MCP9700gradenC; // Dit creëert een globale variabele waarin de gemeten temperatuur wordt opgeslagen. // Setup fase: void setup() { // Voor deze sensor hoeven we niets in de setup fase te doen. } // Loop fase: void loop() { MCP9700(); // Vraag de microcontroller om de functie die de temperatuur uit de sensor ophaalt uit te voeren. } // Functie voor temperatuursensor: float MCP9700() { uint8_t MCP9700i; // Een variabele om in bij te houden hoeveel metingen er genomen zijn. float MCP9700GemVolt; // Een variabele om het gemiddelde van de metingen tijdelijk in op te slaan. // Neem het aantal samples dat bij MCP9700NrSamples is aangegeven per temperatuur meting. for (MCP9700i = 0; MCP9700i < MCP9700NrSamples; MCP9700i++) { MCP9700Metingen[MCP9700i] = analogRead(MCP9700Pin) * (5000.0 / 1023); 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. MCP9700GemVolt = 0; for (MCP9700i = 0; MCP9700i < MCP9700NrSamples; MCP9700i++) { MCP9700GemVolt += MCP9700Metingen[MCP9700i]; } MCP9700GemVolt /= MCP9700NrSamples; // 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. MCP9700gradenC = (MCP9700GemVolt - MCP9700utputVolt) / MCP9700TempCoef; // Haal de MCP9700utputVolt van de MCP9700Volt af en deel het door MCP9700TempCoef. return MCP9700gradenC; }
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.