Een sensor uitlezen
Tot nu toe hebben we de ESP32 vooral gebruikt om iets te doen: we stuurden een GPIO aan en lieten een led knipperen. Nu gaan we de andere kant op werken. In…
Tot nu toe hebben we de ESP32 vooral gebruikt om iets te doen: we stuurden een GPIO aan en lieten een led knipperen.
Nu gaan we de andere kant op werken. In plaats van een uitgang aan te sturen, laten we de ESP32 informatie uit zijn omgeving ontvangen.
Daarvoor gebruiken we een sensor.
In dit hoofdstuk sluiten we een BME280-sensormodule aan. Deze sensor kan drie waarden meten:
- temperatuur;
- relatieve luchtvochtigheid;
- luchtdruk.
We bekijken niet alleen hoe we de meetwaarden op het scherm krijgen. We onderzoeken ook hoe de ESP32 met de sensor communiceert, welke rol een bibliotheek speelt en hoe we vaststellen waar het misgaat wanneer er geen bruikbare gegevens verschijnen.
Van een fysieke eigenschap naar een getal
Een sensor zet een fysieke eigenschap om in informatie die een elektronisch systeem kan verwerken.
Dat kan bijvoorbeeld zijn:
- temperatuur;
- luchtvochtigheid;
- luchtdruk;
- lichtsterkte;
- beweging;
- afstand;
- geluid;
- stroomverbruik;
- de aanwezigheid van een gas.
De sensor in dit hoofdstuk reageert op veranderingen in zijn omgeving. De elektronica in de sensor zet die veranderingen om in digitale meetgegevens. De ESP32 vraagt deze gegevens op en maakt ze beschikbaar voor onze code.
De volledige route wordt dan:
Omgeving → sensor → communicatie → ESP32 → code → seriële monitor
Wanneer een meetwaarde niet klopt, kan het probleem op verschillende plaatsen in deze route zitten. Daarom bekijken we ieder deel afzonderlijk.
Waarom we de BME280 gebruiken
Voor onze eerste sensor gebruiken we een BME280-module.
De BME280 is geschikt voor dit project omdat hij:
- meerdere waarden kan meten;
- met 3,3-voltlogica kan werken;
- digitaal met de ESP32 communiceert;
- weinig aansluitdraden nodig heeft;
- door bestaande Arduino-bibliotheken wordt ondersteund;
- bruikbare gegevens levert voor WiFi en MQTT;
- later onderdeel kan worden van ons eindproject.
Met één sensor kunnen we dus de volledige weg volgen van een lokale meting tot informatie die via het netwerk beschikbaar wordt gemaakt.
Sensor en sensormodule zijn niet hetzelfde
De BME280 zelf is een kleine chip. Deze chip is lastig rechtstreeks op een breadboard aan te sluiten.
Daarom gebruiken we een sensormodule, ook wel een breakoutboard genoemd. Op zo’n klein printplaatje zijn de sensor en aansluitpinnen samengebracht. Afhankelijk van de uitvoering bevat de module ook extra onderdelen, zoals:
- pull-upweerstanden;
- ontkoppelcondensatoren;
- een spanningsregelaar;
- schakelingen voor het aanpassen van signaalniveaus.
Niet iedere BME280-module bevat dezelfde extra elektronica.
De ene module accepteert verschillende voedingsspanningen, terwijl een andere uitsluitend voor 3,3 volt is bedoeld. Ook de volgorde en benaming van de pinnen kunnen verschillen.
Daarom sluiten we een module nooit alleen aan op basis van de kleur van een draad of een willekeurige afbeelding.
Controleer altijd de aanduidingen op je eigen module.
Controleer of je werkelijk een BME280 hebt
De BME280 lijkt sterk op de BMP280. Ook verkooppagina’s en opschriften zijn niet altijd duidelijk.
Het verschil is belangrijk:
- de BME280 meet temperatuur, luchtvochtigheid en luchtdruk;
- de BMP280 meet temperatuur en luchtdruk, maar geen luchtvochtigheid.
Wanneer je per ongeluk een BMP280 hebt ontvangen, kan de bibliotheek voor de BME280 melden dat de sensor niet wordt gevonden.
Bekijk daarom:
- de productomschrijving;
- het opschrift op de verpakking;
- eventuele documentatie van de leverancier;
- de meetfuncties die bij de module worden genoemd.
De tekst op het kleine printplaatje bewijst niet altijd welk type chip erop is geplaatst. Wanneer de sensor ondanks correcte bedrading en het juiste adres niet wordt herkend, nemen we ook een verkeerd geleverd sensortype mee als mogelijke oorzaak.
Hoe de ESP32 met de sensor praat
De BME280 kan op verschillende manieren communiceren. Wij gebruiken I²C.
I²C wordt uitgesproken als I-kwadraat-C en staat voor Inter-Integrated Circuit. Het is een communicatiemethode waarmee elektronische onderdelen via enkele gedeelde draden gegevens kunnen uitwisselen.
Voor onze aansluiting gebruiken we vier verbindingen:
| BME280 | Functie | ESP32 |
|---|---|---|
| VCC, VIN of 3V3 | Voeding | 3V3 |
| GND | Massa | GND |
| SDA | Gegevens | GPIO 21 |
| SCL | Kloksignaal | GPIO 22 |
Bij een algemene ESP32 zijn GPIO 21 en GPIO 22 de gebruikelijke standaardpinnen voor I²C:
- GPIO 21 voor SDA;
- GPIO 22 voor SCL.
Andere pinnen zijn technisch mogelijk, maar door deze standaard te gebruiken sluiten we aan bij veel voorbeelden en bibliotheken.
SDA en SCL
I²C gebruikt twee signaallijnen.
SDA
SDA staat voor Serial Data. Over deze draad worden de gegevens verzonden.
De ESP32 gebruikt SDA onder andere om aan te geven welke informatie hij wil ontvangen. De sensor gebruikt dezelfde lijn om de meetgegevens terug te sturen.
SCL
SCL staat voor Serial Clock. Dit is het kloksignaal waarmee de communicatie wordt gesynchroniseerd.
De ESP32 bepaalt met dit ritme wanneer de bits op de datalijn moeten worden gelezen.
Je hoeft de afzonderlijke bits niet zelf te verwerken. De I²C-bibliotheek en de sensorbibliotheek nemen dat werk van ons over.
Toch is het belangrijk dat je weet dat SDA en SCL verschillende functies hebben. Wanneer je deze draden verwisselt, ontvangt de sensor meestal wel voeding, maar komt er geen communicatie tot stand.
Het I²C-adres
Op dezelfde I²C-bus kunnen meerdere sensoren en andere onderdelen worden aangesloten. De SDA- en SCL-draden worden dan gedeeld.
Om toch met één specifiek onderdeel te kunnen communiceren, heeft ieder apparaat een adres.
De BME280 gebruikt meestal een van deze twee adressen:
0x76
of:
0x77
De notatie 0x geeft aan dat het getal hexadecimaal is geschreven. Je hoeft hexadecimale getallen nu nog niet te kunnen omrekenen. We gebruiken het adres vooral als een herkenbare naam op de I²C-bus.
Welke van de twee adressen jouw module gebruikt, hangt af van de uitvoering en de toestand van een adrespin op de module.
In ons eerste programma proberen we eerst 0x76. Wanneer de sensor daar niet wordt gevonden, proberen we 0x77.
De ledschakeling opruimen
Voor dit hoofdstuk hebben we de ledschakeling uit de vorige hoofdstukken niet nodig.
Koppel eerst de USB-kabel los.
Verwijder daarna rustig:
- de losse led;
- de voorschakelweerstand;
- de jumperdraden naar GPIO 23 en GND.
Je kunt de onderdelen bewaren voor een latere oefening.
Laat de ESP32 spanningsloos terwijl je de BME280 aansluit.
De module bekijken
Zoek op jouw BME280-module naar de aanduidingen bij de aansluitpinnen.
Op een eenvoudige I²C-module zie je vaak:
VCC
GND
SCL
SDA
Een uitgebreidere module kan aansluitingen hebben zoals:
VIN
3Vo
GND
SCK
SDI
SDO
CS
Bij zulke modules kunnen de namen voor meerdere communicatievormen worden gebruikt. Raadpleeg dan de documentatie van precies die module.
Voor onze I²C-aansluiting hebben we uiteindelijk nodig:
- voeding;
- GND;
- SDA;
- SCL.
Sluit extra pinnen zoals CS en SDO niet willekeurig aan. Deze kunnen invloed hebben op de gekozen communicatiemethode en het I²C-adres.
Kies 3,3 volt als veilige basis
De BME280-chip zelf werkt met een lage spanning. Sommige breakoutmodules bevatten een spanningsregelaar en levelshifters, waardoor ze ook met 5 volt overweg kunnen. Andere modules hebben die bescherming niet.
Omdat de ESP32 met 3,3-voltlogica werkt, gebruiken we in deze gids:
3V3 van de ESP32 voor de voeding van de BME280-module.
Gebruik dus niet automatisch de 5V- of VIN-pin.
Controleer daarnaast of jouw specifieke module volgens de documentatie met 3,3 volt kan worden gevoed. Voor een BME280-module die bedoeld is voor gebruik met een ESP32 hoort dit normaal gesproken mogelijk te zijn.
De BME280 aansluiten
Koppel de USB-kabel los voordat je begint.
Maak daarna de volgende verbindingen:
- Verbind VCC, VIN of de aangegeven voedingspin van de BME280 met 3V3 op de ESP32.
- Verbind GND van de BME280 met GND op de ESP32.
- Verbind SDA van de BME280 met GPIO 21.
- Verbind SCL van de BME280 met GPIO 22.
Gebruik bij voorkeur:
- rood voor 3,3 volt;
- zwart of blauw voor GND;
- een andere kleur voor SDA;
- nog een andere kleur voor SCL.
De draadkleuren zijn technisch niet verplicht. Ze helpen ons om de schakeling later sneller te controleren.
Onze verbindingen zijn nu:
ESP32 3V3 → BME280 voeding
ESP32 GND → BME280 GND
ESP32 GPIO 21 → BME280 SDA
ESP32 GPIO 22 → BME280 SCL
Controle vóór het inschakelen
Volg iedere draad van begin tot eind en stel jezelf de volgende vragen:
- Is de voedingspin van de sensor verbonden met 3V3?
- Is GND met GND verbonden?
- Loopt SDA naar GPIO 21?
- Loopt SCL naar GPIO 22?
- Heb ik SDA en SCL niet verwisseld?
- Komt de pinvolgorde overeen met mijn eigen module?
- Zijn er geen losse draden die naastgelegen pinnen raken?
- Is de ESP32 nog steeds ingesteld als het juiste bord in de Arduino IDE?
Sluit de USB-kabel pas aan wanneer deze punten zijn gecontroleerd.
Een bibliotheek gebruiken
De BME280 bewaart zijn meetgegevens in interne registers. We zouden zelf alle communicatie kunnen programmeren, maar daarvoor moeten we precies weten:
- welke opdrachten de sensor verwacht;
- in welke registers de gegevens staan;
- hoe meerdere bytes moeten worden samengevoegd;
- hoe de ruwe waarden worden omgerekend;
- welke kalibratiegegevens in de sensor zijn opgeslagen.
Een bibliotheek neemt deze technische details voor ons over.
Dat betekent niet dat de sensor “vanzelf” werkt. Wij blijven verantwoordelijk voor:
- de juiste bedrading;
- de voedingsspanning;
- het juiste I²C-adres;
- het starten van de sensor;
- het beoordelen van de meetwaarden;
- het reageren op fouten.
Een bibliotheek is gereedschap. Ze maakt een taak toegankelijker, maar kan geen verkeerde aansluiting herstellen.
De benodigde bibliotheken installeren
Open in de Arduino IDE de Library Manager. Deze vind je in de zijbalk of via het menu voor bibliotheken.
Zoek naar:
Adafruit BME280 Library
Installeer de bibliotheek van Adafruit.
Tijdens de installatie kan de Arduino IDE vragen om aanvullende bibliotheken te installeren. De BME280-bibliotheek gebruikt onder andere de Adafruit Unified Sensor-bibliotheek.
Accepteer de installatie van de benodigde afhankelijkheden.
We gebruiken hiermee code die al is geschreven en getest om met de BME280 te communiceren. In ons eigen programma kunnen we daardoor duidelijke opdrachten gebruiken, zoals:
bme.readTemperature();
Ons eerste sensorprogramma
Maak een nieuw programma en voer de volgende code in:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
Adafruit_BME280 bme;
const int sdaPin = 21;
const int sclPin = 22;
const uint8_t bmeAddress = 0x76;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println();
Serial.println("BME280 starten...");
Wire.begin(sdaPin, sclPin);
if (!bme.begin(bmeAddress)) {
Serial.println("BME280 niet gevonden.");
Serial.println("Controleer de bedrading en het I2C-adres.");
while (true) {
delay(1000);
}
}
Serial.println("BME280 gevonden.");
}
void loop() {
float temperatuur = bme.readTemperature();
float luchtvochtigheid = bme.readHumidity();
float luchtdruk = bme.readPressure() / 100.0F;
Serial.print("Temperatuur: ");
Serial.print(temperatuur, 1);
Serial.println(" °C");
Serial.print("Luchtvochtigheid: ");
Serial.print(luchtvochtigheid, 1);
Serial.println(" %");
Serial.print("Luchtdruk: ");
Serial.print(luchtdruk, 1);
Serial.println(" hPa");
Serial.println("--------------------");
delay(2000);
}
Controleer of het juiste bord en de juiste USB-poort zijn geselecteerd. Compileer en upload daarna het programma.
Open vervolgens de seriële monitor en stel de snelheid in op:
115200 baud
De code begrijpen
We bekijken opnieuw stap voor stap wat er gebeurt.
De bibliotheken toevoegen
Bovenaan staan drie regels:
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
Met #include voegen we beschikbare functies en definities uit een bibliotheek aan ons programma toe.
Wire.h verzorgt de I²C-communicatie.
Adafruit_Sensor.h biedt een gemeenschappelijke structuur voor verschillende sensorbibliotheken.
Adafruit_BME280.h bevat de specifieke functies voor de BME280.
Wanneer een van deze bibliotheken ontbreekt, kan de compiler een melding geven zoals:
No such file or directory
Dat is geen probleem in de bedrading. De compiler vertelt ons dat hij een benodigd softwarebestand niet kan vinden.
Een sensorobject maken
Daarna staat:
Adafruit_BME280 bme;
Hiermee maken we in onze code een object met de naam bme.
Je kunt dit object zien als onze softwarematige toegang tot de fysieke sensor. Via bme kunnen we de sensor starten en meetwaarden opvragen.
De naam hadden we anders kunnen kiezen, maar bme maakt duidelijk over welk onderdeel het gaat.
De aansluitingen en het adres vastleggen
We leggen daarna drie waarden vast:
const int sdaPin = 21;
const int sclPin = 22;
const uint8_t bmeAddress = 0x76;
Deze regels vertellen onze code:
- SDA is aangesloten op GPIO 21;
- SCL is aangesloten op GPIO 22;
- de sensor wordt eerst gezocht op adres 0x76.
De code en de fysieke bedrading moeten met elkaar overeenkomen.
Als we in de code GPIO 21 gebruiken voor SDA, maar de draad fysiek op GPIO 19 plaatsen, kan de communicatie niet werken.
De seriële monitor starten
In setup() staat:
Serial.begin(115200);
delay(1000);
De eerste regel start de seriële communicatie met een snelheid van 115200 baud.
De korte wachttijd geeft de seriële verbinding en de ESP32 tijd om na het opstarten gereed te komen. Daarna schrijven we enkele herkenbare berichten naar de seriële monitor.
De lege regel:
Serial.println();
zorgt alleen voor wat extra ruimte in de uitvoer.
De I²C-verbinding starten
Met:
Wire.begin(sdaPin, sclPin);
starten we de I²C-communicatie op de gekozen pinnen.
Omdat sdaPin de waarde 21 bevat en sclPin de waarde 22, gebruikt de ESP32:
- GPIO 21 als SDA;
- GPIO 22 als SCL.
We noemen de pinnen bewust in de code. Daardoor hoeven we niet alleen te vertrouwen op standaardinstellingen die bij een ander bord mogelijk afwijken.
Controleren of de sensor reageert
De volgende regel probeert de BME280 te starten:
bme.begin(bmeAddress)
Deze functie geeft aan of er een geschikte sensor op het opgegeven adres is gevonden.
We plaatsen er een uitroepteken voor:
if (!bme.begin(bmeAddress))
Het uitroepteken betekent hier niet.
De volledige regel kun je daarom lezen als:
Als de BME280 niet kan worden gestart, voer dan de code tussen de accolades uit.
De seriële monitor toont vervolgens:
BME280 niet gevonden.
Controleer de bedrading en het I2C-adres.
Daarna komt het programma in:
while (true) {
delay(1000);
}
while (true) betekent dat dit blok eindeloos wordt herhaald.
We stoppen het programma hier bewust. Het heeft weinig zin om meetwaarden op te vragen bij een sensor die niet is gevonden. Zonder deze controle zouden we mogelijk ongeldige waarden tonen en de indruk wekken dat er een echte meting is gedaan.
Meetwaarden opvragen
Wanneer de sensor correct is gestart, bereikt de ESP32 loop().
Daar maken we drie variabelen:
float temperatuur = bme.readTemperature();
float luchtvochtigheid = bme.readHumidity();
float luchtdruk = bme.readPressure() / 100.0F;
Een float is een getal waarin ook cijfers achter de komma kunnen worden bewaard.
De bibliotheek geeft:
- temperatuur in graden Celsius;
- luchtvochtigheid in procenten;
- luchtdruk oorspronkelijk in pascal.
Voor luchtdruk gebruiken we vaak hectopascal, afgekort als hPa. Daarom delen we de uitkomst door 100:
bme.readPressure() / 100.0F
Een luchtdruk van 101325 pascal wordt dan:
1013,25 hPa
De letter F achter 100.0 vertelt de compiler dat we met een float rekenen.
Meetwaarden afdrukken
De meetwaarden worden met Serial.print() en Serial.println() naar de seriële monitor gestuurd.
Bijvoorbeeld:
Serial.print(temperatuur, 1);
De 1 geeft aan dat we één cijfer achter de komma willen tonen.
Een waarde kan daardoor verschijnen als:
21.7
De Arduino IDE gebruikt in getallen een punt als decimaalteken. Dat is normaal, ook wanneer we in Nederlandse tekst meestal een komma gebruiken.
Serial.print() blijft op dezelfde regel schrijven. Serial.println() gaat na de tekst naar een nieuwe regel.
Daarom vormen deze opdrachten samen één leesbare regel:
Serial.print("Temperatuur: ");
Serial.print(temperatuur, 1);
Serial.println(" °C");
De meting herhalen
Aan het einde van loop() staat:
delay(2000);
De ESP32 wacht twee seconden voordat hij de sensor opnieuw uitleest.
Sneller meten levert niet automatisch betere informatie op. Temperatuur, luchtvochtigheid en luchtdruk veranderen meestal niet van het ene op het andere milliseconde.
Een rustig meetinterval:
- maakt de seriële monitor beter leesbaar;
- voorkomt onnodige communicatie;
- levert voldoende informatie voor onze oefening.
Later, wanneer de ESP32 ook WiFi- en MQTT-taken moet uitvoeren, bekijken we opnieuw hoe we de timing van het programma organiseren.
Wat verwachten we te zien?
Wanneer de sensor correct is aangesloten en wordt herkend, verschijnt in de seriële monitor iets als:
BME280 starten...
BME280 gevonden.
Temperatuur: 21.7 °C
Luchtvochtigheid: 48.3 %
Luchtdruk: 1008.6 hPa
--------------------
Na ongeveer twee seconden verschijnt een nieuwe meting.
Jouw waarden zullen anders zijn. Dat is niet meteen een probleem. Een sensor meet zijn eigen omgeving, niet de waarden uit ons voorbeeld.
Een meetwaarde is niet automatisch de waarheid
Het feit dat een sensor een getal terugstuurt, betekent niet dat dit getal zonder nadenken als waarheid moet worden behandeld.
Een meting wordt beïnvloed door:
- de nauwkeurigheid van de sensor;
- de plaats van de sensor;
- warmte van de ESP32;
- luchtstroming;
- direct zonlicht;
- warmte van je hand;
- vocht in de omgeving;
- de tijd die de sensor nodig heeft om zich aan te passen;
- eventuele afwijkingen tussen afzonderlijke sensoren.
Wanneer de BME280 vlak naast de ESP32 ligt, kan de warmte van het ontwikkelbord de temperatuurmeting beïnvloeden.
Plaats je de sensor in een gesloten behuizing, dan meet hij mogelijk vooral de temperatuur binnen die behuizing.
De vraag is daarom niet alleen:
Welke waarde geeft de sensor?
Maar ook:
Wat meet de sensor op deze plaats en onder deze omstandigheden?
Een eenvoudige praktijktest
Laat de sensor enkele minuten rustig liggen en noteer de waarden.
Houd daarna je hand in de buurt van de sensor zonder hem direct aan te raken.
Je kunt mogelijk zien dat:
- de temperatuur langzaam stijgt;
- de luchtvochtigheid verandert;
- de luchtdruk vrijwel gelijk blijft.
Adem niet van zeer dichtbij op de sensor. Condens en een plotseling zeer hoge luchtvochtigheid kunnen de meting tijdelijk sterk beïnvloeden.
Het doel is niet om een exacte waarde af te dwingen. We willen zien of de metingen op een begrijpelijke manier reageren op een verandering in de omgeving.
Wanneer de sensor niet wordt gevonden
Verschijnt de melding:
BME280 niet gevonden.
dan weten we al verschillende dingen.
De ESP32:
- is gestart;
- voert onze code uit;
- kan berichten naar de seriële monitor sturen;
- bereikt de controle van de sensor.
We hoeven dus niet meer te zeggen dat “niets werkt”. Het probleem bevindt zich waarschijnlijk in een kleiner gebied:
Voeding, bedrading, I²C-adres, module of bibliotheek
Koppel de USB-kabel los voordat je de bedrading aanpast.
Controleer eerst de voeding
Controleer of:
- de voedingspin van de sensor met 3V3 is verbonden;
- de GND-pin van de sensor met GND is verbonden;
- de draden in de juiste rijen van het breadboard zitten;
- de pinvolgorde overeenkomt met jouw module.
Met een multimeter kun je de spanning direct op de module meten.
Plaats:
- de zwarte meetpen op GND van de module;
- de rode meetpen op de voedingspin van de module.
Je verwacht ongeveer 3,3 volt.
Meet je wel 3,3 volt? Dan weet je dat de voeding de module bereikt. Dat bewijst nog niet dat de communicatie werkt, maar we hebben één mogelijke oorzaak onderzocht.
Controleer SDA en SCL
Volg beide signaaldraden van begin tot eind:
- SDA van de module moet naar GPIO 21;
- SCL van de module moet naar GPIO 22.
Controleer de tekst bij de pinnen, niet alleen de positie.
Bij sommige modules wordt SCL aangeduid als SCK en SDA als SDI. Dat kan samenhangen met ondersteuning voor zowel I²C als SPI. Raadpleeg bij twijfel de documentatie van die specifieke module.
Verwisselde SDA- en SCL-draden beschadigen de sensor normaal gesproken niet direct, maar communicatie komt dan niet tot stand.
Probeer het andere adres
Als de bedrading correct lijkt, kan de module adres 0x77 gebruiken in plaats van 0x76.
Verander:
const uint8_t bmeAddress = 0x76;
in:
const uint8_t bmeAddress = 0x77;
Upload daarna de code opnieuw.
Verander alleen het adres. Laat de rest van de bedrading en code gelijk. Wanneer de sensor nu wel wordt gevonden, hebben we aangetoond dat het I²C-adres de oorzaak was.
De I²C-bus onderzoeken
Wanneer beide adressen niet werken, kunnen we de I²C-bus scannen.
Een I²C-scanner probeert alle mogelijke adressen en meldt welke apparaten reageren. Daarmee beantwoorden we een gerichte vraag:
Ziet de ESP32 überhaupt een I²C-apparaat?
Upload hiervoor tijdelijk het volgende programma:
#include <Wire.h>
const int sdaPin = 21;
const int sclPin = 22;
void setup() {
Serial.begin(115200);
delay(1000);
Wire.begin(sdaPin, sclPin);
Serial.println();
Serial.println("I2C-scan gestart.");
}
void loop() {
int aantalApparaten = 0;
for (uint8_t adres = 1; adres < 127; adres++) {
Wire.beginTransmission(adres);
uint8_t resultaat = Wire.endTransmission();
if (resultaat == 0) {
Serial.print("Apparaat gevonden op adres 0x");
if (adres < 16) {
Serial.print("0");
}
Serial.println(adres, HEX);
aantalApparaten++;
}
}
if (aantalApparaten == 0) {
Serial.println("Geen I2C-apparaten gevonden.");
} else {
Serial.print("Aantal gevonden apparaten: ");
Serial.println(aantalApparaten);
}
Serial.println("--------------------");
delay(5000);
}
Open de seriële monitor op 115200 baud.
Een correct aangesloten BME280 geeft meestal:
Apparaat gevonden op adres 0x76
of:
Apparaat gevonden op adres 0x77
Wat vertelt de scanner ons?
De scanner verdeelt het probleem in kleinere delen.
De scanner vindt 0x76
De voeding, bedrading en I²C-communicatie werken waarschijnlijk. Gebruik in het sensorprogramma adres 0x76.
De scanner vindt 0x77
De verbinding werkt, maar het sensorprogramma gebruikte het verkeerde adres. Verander het adres naar 0x77.
De scanner vindt een ander adres
Er reageert een I²C-apparaat, maar mogelijk niet het apparaat dat we verwachten. Controleer het type module en de bijbehorende documentatie.
De scanner vindt niets
Dan richten we het onderzoek op:
- voeding;
- GND;
- SDA en SCL;
- een slechte jumperdraad;
- verkeerde pinnamen;
- een defecte module;
- ontbrekende pull-upweerstanden op een kale of afwijkende module.
De scanner bewijst niet dat iedere meetfunctie correct werkt. Hij toont alleen dat een apparaat op een adres reageert.
Onmogelijke meetwaarden herkennen
Soms wordt de sensor wel gevonden, maar verschijnen er onbruikbare waarden.
Je kunt bijvoorbeeld zien:
nan
nan staat voor not a number. De software heeft dan geen geldig getal kunnen maken van het resultaat.
Andere verdachte waarden zijn:
- een temperatuur die onmogelijk bij de omgeving past;
- voortdurend exact dezelfde waarde terwijl de omgeving verandert;
- plotselinge extreme sprongen;
- nulwaarden voor alle metingen;
- luchtvochtigheid buiten een logisch bereik.
Behandel zulke waarden niet automatisch als echte metingen.
Stel eerst vast:
- treedt het bij alle meetwaarden op;
- gebeurt het voortdurend of af en toe;
- verandert het wanneer je de sensor opnieuw aansluit;
- is het juiste sensortype gebruikt;
- is de bibliotheek correct geïnstalleerd;
- blijft de voedingsspanning stabiel;
- zijn de verbindingen stevig.
Een losse verbinding herkennen
Breadboards en jumperdraden zijn handig, maar niet iedere verbinding is even betrouwbaar.
Wanneer de meetwaarden verdwijnen zodra je een draad aanraakt, kan er sprake zijn van:
- een versleten jumperdraad;
- een verbogen aansluitpin;
- een slecht contact in het breadboard;
- een draad die niet volledig is ingestoken;
- een gebroken soldeerverbinding op de module.
Beweeg niet voortdurend alle draden tegelijk. Test één verbinding per keer.
Je kunt ook een jumperdraad vervangen door een exemplaar waarvan je weet dat het werkt. Noteer welke draad je hebt vervangen en wat het effect was.
Temperatuur vergelijken
Plaats een andere thermometer in de buurt van de BME280 en laat beide apparaten voldoende tijd acclimatiseren.
Vergelijk daarna de waarden.
Verwacht niet dat twee verschillende sensoren exact hetzelfde getal tonen. Ze kunnen verschillen door:
- meetnauwkeurigheid;
- reactietijd;
- luchtstroming;
- hun exacte positie;
- warmte van de elektronica;
- afronding van de weergegeven waarde.
Een klein verschil betekent niet direct dat een sensor defect is.
Kijk eerst of de richting en veranderingen logisch zijn. Wanneer de omgeving warmer wordt, moeten beide sensoren uiteindelijk een stijging laten zien.
Luchtdruk en hoogte
De BME280 meet de luchtdruk op de plaats waar de sensor zich bevindt.
Een weerwebsite kan een andere waarde tonen, omdat luchtdruk in weersverwachtingen vaak wordt omgerekend naar zeeniveau. Ook hoogteverschillen en lokale weersomstandigheden hebben invloed.
Vergelijk de ruwe meting daarom niet zonder meer met een waarde uit een weerapp.
Later kunnen we, als dat voor het project nuttig is, een correctie voor de hoogte toepassen. Voor nu gebruiken we de werkelijk gemeten plaatselijke luchtdruk.
Bibliotheekcode is geen garantie
Het gebruik van een bekende bibliotheek helpt ons, maar ontslaat ons niet van controle.
Een voorbeeldprogramma kan uitgaan van:
- een ander bord;
- andere I²C-pinnen;
- adres 0x77 in plaats van 0x76;
- een specifieke uitvoering van de module;
- een oudere bibliotheekversie.
Wanneer voorbeeldcode niet direct werkt, betekent dat niet automatisch dat de code slecht is of jouw sensor defect is. Het kan simpelweg betekenen dat de aannames van het voorbeeld niet overeenkomen met jouw situatie.
Onze taak is dan om die aannames zichtbaar te maken en één voor één te controleren.
De meetgegevens voorbereiden voor later
Op dit moment tonen we de waarden alleen in de seriële monitor:
Temperatuur: 21.7 °C
Luchtvochtigheid: 48.3 %
Luchtdruk: 1008.6 hPa
De waarden zijn in onze code ook opgeslagen in variabelen:
temperatuur
luchtvochtigheid
luchtdruk
Dat is belangrijk, want we kunnen dezelfde variabelen later gebruiken om:
- een waarschuwing te geven;
- een led aan te sturen;
- waarden op een display te tonen;
- gegevens via WiFi te versturen;
- MQTT-berichten te publiceren;
- meetwaarden in Home Assistant zichtbaar te maken.
De sensor hoeft daarvoor niet anders te meten. We veranderen vooral wat we met de meetgegevens doen.
Een kleine oefening
Voeg aan het programma een eenvoudige beoordeling van de temperatuur toe.
Plaats na het afdrukken van de meetwaarden:
if (temperatuur > 25.0) {
Serial.println("Het is warmer dan 25 graden.");
} else {
Serial.println("De temperatuur is 25 graden of lager.");
}
Voorspel eerst wat de seriële monitor in jouw omgeving zal tonen.
Upload daarna de code en vergelijk de melding met de gemeten temperatuur.
Met deze toevoeging gaan we van alleen meten naar verwerken:
Sensor → meetwaarde → vergelijking → conclusie
Dat is dezelfde basisstructuur die we later gebruiken om een automatisch systeem een beslissing te laten nemen.
Wat je uit dit hoofdstuk kunt meenemen
We hebben een sensor aangesloten en de volledige route van fysieke meting naar bruikbare variabele gevolgd.
Daarbij heb je ontdekt dat:
- een sensor een fysieke eigenschap omzet in gegevens;
- een sensormodule meer kan bevatten dan alleen de sensorchip;
- de BME280 temperatuur, luchtvochtigheid en luchtdruk meet;
- een BMP280 geen luchtvochtigheid meet;
- we de sensor veilig met 3,3 volt voeden;
- I²C gebruikmaakt van SDA en SCL;
- GPIO 21 en GPIO 22 de gebruikelijke I²C-pinnen van onze ESP32 zijn;
- een I²C-apparaat een adres nodig heeft;
- de BME280 meestal adres 0x76 of 0x77 gebruikt;
- een bibliotheek ingewikkelde communicatie toegankelijker maakt;
- onze code eerst controleert of de sensor werkelijk is gevonden;
- de seriële monitor meetwaarden en foutmeldingen zichtbaar maakt;
- een I²C-scanner helpt om communicatieproblemen af te bakenen;
- een getal niet automatisch een betrouwbare meting is;
- plaatsing, voeding en omgeving invloed hebben op de meetwaarde;
- de meetgegevens in variabelen beschikbaar zijn voor volgende stappen.
De belangrijkste verandering is dat onze ESP32 nu niet alleen opdrachten uitvoert. Hij ontvangt informatie uit de echte wereld en kan daar met code op reageren.
In het volgende hoofdstuk verbinden we de ESP32 met WiFi. Daarmee zetten we de eerste stap om onze meetwaarden buiten de USB-kabel en de seriële monitor beschikbaar te maken.
Technische naslag
De standaard I²C-pinnen voor een algemene ESP32 en de actuele functies van de I²C-bibliotheek staan in de officiële Arduino-ESP32 I²C-documentatie van Espressif. De BME280-bibliotheek en voorbeeldcode zijn beschikbaar via de officiële Adafruit BME280 Library.