De Programmeerbare Plantenkas: Sensordata opslaan in een CSV-bestand op een SD kaart

De Programmeerbare Plantenkas: Sensordata opslaan in een CSV-bestand op een SD kaart

In deze tutorial laten we zien hoe je sensor data, in dit geval van een Grove Temperature & Humidity sensor met DHT11 chip, op kunt slaan in een CSV-bestand op een SD kaart met een Arduino microcontroller of een andere microcontroller.

Voorbereiding

Voordat je een nieuwe microSD kaart kunt gebruiken, moet deze meestal eerst geformatteerd worden naar FAT16 of FAT32. Hoe dit precies moet, verschilt per computersysteem. Bij Windows klik je in het “computer” scherm (start > computer) met de rechtermuis op de SD kaart en selecteer je vervolgens de optie "formatteren". In het scherm dat dan op komt, selecteer je "FAT32" en klik je op "start".  Bij MAC ga je naar het "schijfhulpprogramma" en selecteer je de SD kaart in het programma. Vervolgens klik je op “wis” en geef je in het menu aan dat je de kaart in FAT32 wilt.

formatteren, ms-dos, fat32
Op MAC computers wordt FAT32 ook wel aan gegeven als MS-DOS (FAT32).

Aansluiten

Om data van een Grove Temperature & Humidity sensor met DHT11 chip op een SD kaart op te slaan, moeten er drie dingen aangesloten worden: Er moet een Ethernet Shield met SD kaarthouder op de Arduino UNO geschoven worden, er moet vervolgens een Grove Base Shield op de Ethernet Shield geschoven worden, en dan moet de sensor worden aangesloten. Hieronder leggen we onderdeel voor onderdeel uit hoe dit het beste gedaan kan worden.

aansluitschema
Hierboven is het aansluitschema voor de Grove Temperature & Humidity sensor op de Grove Base Shield schematisch weergegeven.

Het aansluiten van de Seeed Studio Ethernet Shield (W5500)

Er zijn verschillende manieren om een microSD kaart op een Arduino UNO of een andere microcontroller aan te sluiten. In deze tutorial werken wij met een Seeed Studio Ethernet Shield (W5500). Deze ethernet shield is vergelijkbaar met de Ethernet Shield 2 van Arduino of een merkloos ethernet shield met een W5100 chip. Wij kiezen er vooral voor om een ethernet shield met SD kaart houder te gebruiken, omdat dit eenvoudig is. Je kunt een ethernet shield namelijk eenvoudig op de Arduino UNO schuiven, waardoor er geen extra kabels en soldeer klusjes aan te pas komen. Het nadeel is wel dat een ethernet shield in de meeste gevallen duurder is dan een losse SD kaart module.

ethernet shield, microsd kaart
De meeste Ethernet Shields hebben een microSD kaart houder, bij deze shield kun je de microSD kaart houder rechtsonder zien.

Het aansluiten van de Grove Temperature & Humidity Sensor (DHT11)

Als voorbeeld gebruiken we een Grove Temperature & Humidity sensor met een DHT11 chip. Uit deze sensor kun je twee waardes halen, namelijk de temperatuur en de luchtvochtigheid. In dit voorbeeld bepalen we elke 15 minuten hoe warm en vochtig het is. Deze data slaan we in twee kolommen op in een CSV bestand. Een CSV bestand kan door datasheet programma’s, zoals Excel of Numbers, eenvoudig worden uitgelezen. Ook kunnen deze bestanden uitgelezen en geanalyseerd worden door programma’s zoals R, Python, SPSS en Matlab.

Grove Temperature & Humidity, DHT11
De Grove Temperature & Humidity sensor met een DHT11 chip.

Om de Grove Temperature & Humidity sensor aan te sluiten, maken we gebruik van een Grove Base Shield. Deze Grove Shield schuif je eenvoudig boven op de Ethernet Shield. De microcontroller bestaat dan dus uit drie lagen: onderop de Arduino UNO, in het midden de Seeed Studio Ethernet Shield (W5500), en bovenop de Grove Base Shield. De Grove sensors komen met een speciale Grove aansluitkabel. Deze steek je simpelweg in de witte connector op de sensor en vervolgens in een digitale poort van de Grove Base Shield. In dit voorbeeld gebruiken wij de D5 connector op de Grove Base Shield om de Grove Temperature & Humidity sensor op aan te sluiten.

Grove Temperature & Humidity sensor, grove base shield, aansluiting
In dit voorbeeld verbinden we de Grove Temperature & Humidity sensor aan de D5 connector van de Grove Base Shield.

Programmeren

De code voor deze tutorial bestaat uit twee onderdelen: Het instellen en activeren van de DHT11 temperatuursensor en het creëren van een CSV-bestand op de SD kaart. De code die we gebruiken voor de DHT11 temperatuursensor staat uitgebreid beschreven in het artikel "De Programmeerbare Plantenkas: De DHT11 Temperatuursensor Aansluiten En Programmeren Om De Temperatuur Te Meten". Om te voorkomen dat we ons te veel herhalen, vertellen we daarom weinig over het deel van de code dat de temperatuursensor bediend.

Om onze data op de SD kaart te kunnen opslaan, maken we gebruik van de SD van Arduino bibliotheek die via de Arduino IDE te downloaden is. Deze bibliotheek neemt behoorlijk wat geheugen in beslag. Voor grotere projecten waarbij data wordt opgeslagen, is het daarom vrijwel altijd nodig om met een microcontroller met een groot geheugen, zoals een Arduino MEGA, te werken.

In de voorbereidingsfase van deze code stellen we eerst de DHT11 sensor in, door de bijbehorende bibliotheek te activeren, te vertellen op welke digitale pin de DHT11 sensor aangesloten zit, en het type sensor te definiëren. Nadat dit gebeurd is, gaan we de bibliotheek voor de SD kaart downloaden. Dit doen we met het commando #include <SD.h>.  Vervolgens moeten we de bibliotheek vertellen op welke chip de SD kaart zit aangesloten, met het commando const int chipSelect = 4;. Bij de meeste Arduino microcontrollers is dit chip 4, maar check dit altijd even voordat je aan de slag gaat.

In de setup fase zetten we eerst de communicatie met de DHT11 temperatuursensor aan. Daarna beginnen we met het instellen van de SD kaart. Dit doen we met het commando SD.begin(chipSelect);. Dit commando zorgt ervoor dat de communicatie tussen de SD kaart en de SD bibliotheek wordt gestart. Vervolgens openen we een CSV-bestand op de SD kaart met het commando File dataFile = SD.open("temp.csv", FILE_WRITE);. Als het bestand "temp.csv" nog niet bestaat, dan zorgt dit commando ervoor dat dit bestand wordt gecreëerd. Als het bestand wel al bestaat, dan opent dit commando het bestaande bestand. 

Om het later makkelijker te maken om te begrijpen wat er in het CSV-bestand staat, laten we eerst een header in het CSV-bestand printen. Dit doen we door eerst een header aan te maken, met het commando String header = "Temperatuur in graden Celsius";. In dit voorbeeld hebben we maar één kolom. Mocht je meerdere kolommen hebben, dan zet je een komma tussen de namen van de verschillende kolommen, bijvoorbeeld "Temperatuur,Luchtvochtigheid,Licht". Om de header in het CSV-bestand te zetten gebruiken we vervolgens het commando dataFile.println(header);.  Dit commando print de header op een nieuwe regel in het CSV-bestand temp.csv, dat we zojuist gemaakt en/of geopend hebben. Het is belangrijk om hier println te gebruiken in plaats van alleen print, want println zorgt ervoor dat deze data op een nieuwe regel terecht komt. Het dataverwerkingsprogramma dat je later gaat gebruiken weet dan later dat dit om een nieuwe rij gaat. Om de header daadwerkelijk op te slaan, sluiten we af met het commando dataFile.close();. Dit commando moeten we altijd geven als we iets nieuws hebben toegevoegd aan het CSV-bestand, anders wordt het niet opgeslagen. 

In de loop fase van het programma vragen we de microcontroller eerst om de temperatuur uit de DHT11 temperatuursensor te halen. Om de code overzichtelijk te houden, staan de commando's die daar voor nodig zijn in een aparte functie, die we GROVEDHT11() hebben genoemd. Om de nieuwe temperatuur, die in de globale variabele DHT11gradenC is opgeslagen, in het CSV-bestand op te slaan, openen we eerst weer het CSV-bestand op de SD kaart. Dit doen we weer met het commando File dataFile = SD.open("temp.csv", FILE_WRITE);. Om de temperatuur in een nieuwe rij te zetten, gebruiken we het commando dataFile.println(DHT11gradenC);. Mocht je data van meerdere sensoren willen opslaan, dan print je na deze regel eerst het commando dataFile.print(","); om een komma na de temperatuur te zetten, en dan dataFile.println(nieuwesensor); om de meting van de nieuwe sensor af te printen. Zoals je ziet beginnen we een nieuwe rij dus met het commando .println, en gebruiken we .print voor de data die in dezelfde rij moet staan. Eventueel kun je alle sensor data, gescheiden door komma's, eerst in een string object zetten, en dan in één keer in het CSV-bestand laten printen. In het artikel "De Programmeerbare Plantenkas: Sensordata opgeslagen in een CSV-bestand op een SD kaart voorzien van data en tijd met een Real Time Clock Module" geven we hier een voorbeeld van. Om de nieuwe rij gegevens op te slaan, sluiten we weer af met het commando dataFile.close();

ARDUINO IDE CODE


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

   Deze code is gemaakt voor een Ethernet Shield met
   microSD kaart houder en een DHT11 temperatuursensor.

   Deze code maakt gebruikt van de SD bibliotheek.
   Meer info over deze bibliotheek vindt je hier:
   https://www.arduino.cc/en/Reference/SD
   Deze code maakt ook gebruikt van de DHT bibliotheek
   voor de Grove Temperature and Humidity Sensor
   van Seeed Studio.
   Meer info over deze bibliotheek vindt je hier:
   https://github.com/Seeed-Studio/Grove_Temperature_And_Humidity_Sensor

   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 er niets in de Serial Monitor
   af geprint.
*/

// Voorbereiding:
#include <DHT.h> // Dit laadt de bibliotheek die nodig is om de temperatuursensor te lezen.
#define DHTPIN 6 // Dit geeft aan op welke digitale input de sensor is aangesloten, in dit geval D6.
#define DHTTYPE DHT11 // Dit geeft aan om wel type DHT sensor het gaat, in dit geval DHT11, maar er zijn ook andere zoals DHT21 en DHT22. 
DHT dht11(DHTPIN, DHTTYPE); // Dit verteld de bibliotheek hoe we de sensor gaan noemen, welke sensor het is en waar hij op aan gesloten is.
float DHT11gradenC; // Dit creëert een globale variabele waarin de gemeten temperatuur wordt opgeslagen.
#include <SD.h> // Dit laadt de bibliotheek die nodig is om de SD kaart te bedienen.
const int chipSelect = 4; // Vertel op welke pin de SD kaart zit aangesloten, bij de Arduino UNO en MEGA die wij gebruiken is dit pin 4.

// Setup fase:
void setup() {
  dht11.begin(); // Zet de communicatie tussen de microcontroller en de sensor aan.
  SD.begin(chipSelect); // Zet de communicatie tussen de microcontroller en de microSD kaart aan.
  File dataFile = SD.open("temp.csv", FILE_WRITE); // Open een (nieuw) CSV bestand op de microSD kaart.
  String header = "Temperatuur in graden Celsius";  // Header (eerste rij) van CSV bestand met namen van kolommen.
  dataFile.println(header); // Print de header in het CSV bestand.
  dataFile.close(); // Sluit het CSV bestand om de wijzigingen op te slaan.
}

// Loop fase:
void loop() {
  GROVEDHT11(); // Vraag de microcontroller om de functie die de temperatuur uit de sensor ophaalt uit te voeren.
  File dataFile = SD.open("temp.csv", FILE_WRITE); // Open het CSV bestand op de microSD kaart.
  dataFile.println(DHT11gradenC); // Print een nieuwe rij met de temperatuur.
  dataFile.close(); // Sluit het CSV bestand om de wijzigingen op te slaan.
}

// Functie voor temperatuursensor:
float GROVEDHT11() {
  DHT11gradenC = dht11.readTemperature(); // Dit haalt de temperatuur uit de sensor op.
  return DHT11gradenC; // De functie zal de waarde van variabele AHT20gradenC updaten met de gemmeten temperatuur.
}


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.