Ik vind het belangrijk dat Bas on Tech door iedereen kosteloos gebruikt kan worden.
Help mij de toekomst van Bas on Tech te verzekeren. Je donatie zal o.a. worden gebruikt voor hosting, video's en onderhoud.
Alvast bedankt!
iDEAL en Bancontact vind je onder het "Direct Debit" tabblad in de 4e stap.
In deze les leer je hoe je de CZN-15E geluidssensor uitleest en op de seriële plotter van de Arduino IDE weergeeft. Daarnaast leer je wat data sampling is, en hoe je dit kunt gebruiken om de geluidssterkte te benaderen. 🤓
Onderaan op deze pagina vind je de knop lesmateriaal waarmee je het lesmateriaal kunt downloaden. Dit materiaal bestaat uit de code, schakelschema en andere bestanden die in de les worden gebruikt.
De CZN-15E geluidssensor kan meten of er geluid aanwezig is. Hiermee is het bijvoorbeeld mogelijk om een klap-sensor te maken. Anders dan bij een microfoon meet deze niet de frequentie of volume van het geluid. Het is een binaire sensor die alleen aangeeft of er geluid waargenomen wordt.
In het bovenste deel van de figuur zie je geluidsgolven de sensor bereiken. De microfoon zet deze om naar een weerstand. Deze weerstand veranderd naar mate het geluid harder of zachter is. Vervolgens bepaald de sensor of de weerstand boven een drempelwaarde komt. Zodra dit het geval is veranderd de OUT
pin op de sensor van LOW
naar HIGH
.
De gevoeligheid van de sensor is aanpasbaar. Bovenop de sensor zit een blauwe vierkant blokje. Met een kleine schroevendraaier kun je het midden naar links of rechts draaien. Hiermee stel je de juiste gevoeligheid in.
Connect the sensor to your Arduino according to the diagram below.
Hierbij gebruiken we de volgende jumper wires
5V
op de Arduino -> VCC pin van de sensorGND
op de Arduino -> GND pin van de sensorPin 8
op de Arduino -> OUT pin van de sensorDe onderstaande code leest de OUT_PIN
(pin 8) uit en stuurt vervolgens de gemeten waarde naar de seriële monitor.
1 const int OUT_PIN = 8;
2
3 void setup() {
4 Serial.begin(9600);
5 }
6
7 void loop() {
8 Serial.println(digitalRead(OUT_PIN));
9 }
Upload deze code naar je Arduino en open de seriële monitor in de Arduino IDE:
Als het goed is zie je allemaal 1
en 0
voorbij komen als je geluid maakt. Hierbij is 0
voor stilte en 1
voor als er geluid is.
Naast de seriële monitor heeft de Arduino nog een handig hulpmiddel: de seriële plotter. Met dit hulpmiddel kun je data realtime in de tijd laten weergeven. Dit kan bijvoorbeeld gebruikt worden voor temperatuurgrafieken.
Je kunt de de seriële plotter openen via het menu bovenin de IDE:
Als het goed is worden nu de enen en nullen van de seriële monitor in een grafiek weergegeven.
Voor deel 2 van deze les gaan we gebruik maken van data sampling. Dit houdt in dat we op een vast interval (sample tijd), bijvoorbeeld 10ms, een bepaalde waarde gaan meten. Zo je bijvoorbeeld gaan tellen hoe vaak een bepaalde waarde binnen de sample tijd voor is gekomen. De resultaat van deze telling vervolgens in een grafiek weer te geven.
We beginnen met definiëren van twee constanten en vier variabelen:
1 const int OUT_PIN = 8;
2 const int SAMPLE_TIME = 10;
3 unsigned long millisCurrent;
4 unsigned long millisLast = 0;
5 unsigned long millisElapsed = 0;
6 int sampleBufferValue = 0;
OUT_PIN
is de pin waarop we de sensor hebben aangesloten.SAMPLE_TIME
is het aantal milliseconden waarbinnen we de data voor één sample meten.millisCurrent
, millisLast
en millisElapsed
gebruiken we om bij te houden hoeveel tijd er verstreken is.sampleBufferValue
gebruiken we om op te slaan hoe vaak er binnen de sample tijd geluid is geweest.1 void setup()
2 {
3 Serial.begin(9600);
4 }
In de setup()
doen we niets anders dan de seriële monitor op 9600 Baud in te stellen.
1 void loop() {
2
3 millisCurrent = millis();
4 millisElapsed = millisCurrent - millisLast;
5
6 if (digitalRead(OUT_PIN) == LOW) {
7 sampleBufferValue++;
8 }
9
10 if (millisElapsed > SAMPLE_TIME) {
11 Serial.println(sampleBufferValue);
12 sampleBufferValue = 0;
13 millisLast = millisCurrent;
14 }
15
16 }
De loop()
functie bestaat uit 3 delen:
Bij het berekenen van de verstreken tijd maken we gebruik van de mills() functie. Deze geeft het aantal verstreken milliseconden terug sinds de Arduino is opgestart. Het teruggeven getal is van het type unsigned long
. Na ongeveer na 50 dagen is het hoogste getal bereikt, de Arduino zal dan weer opnieuw vanaf 0 beginnen te tellen.
1 millisCurrent = millis();
2 millisElapsed = millisCurrent - millisLast;
Eerst slaan we het aantal verstreken milliseconden in de variabele millisCurrent
op. Hierna kunnen we bereken hoeveel tijd er is verstreken sinds de vorige keer door hier millisLast
vanaf te trekken. Dit slaan we op in de variabele millisElapsed
. Bij de eerste keer staat millisLast
nog op 0, en is dus millisElapsed
gelijk aan millisCurrent
.
Voor het uitlezen van de sensor maken we gebruik van digitalRead()
.
1 if (digitalRead(OUT_PIN) == LOW) {
2 sampleBufferValue++;
3 }
Als de uitgelezen waarde gelijk is aan LOW
verhogen we sampleBufferValue
met 1. De verkorte schrijfwijze hiervoor is sampleBufferValue++
.
🎓 Kun je aangeven waarom we hier kijken of de sensor LOW
is?
We hebben nog geen manier om te bepalen of de sampletijd verstreken is. Dat doen we in het laatste deel van de code.
1 if (millisElapsed > SAMPLE_TIME) {
2 Serial.println(sampleBufferValue);
3 sampleBufferValue = 0;
4 millisLast = millisCurrent;
5 }
Op het moment dat de verstreken tijd (millisElapsed
) groter is dan de tijd dat een sample mag duren, gaan we een aantal dingen doen. Als eerste printen we de waarde van de buffer (sampleBufferValue
) naar de seriële monitor. sampleBufferValue
bevat hoe vaak de sensor in de huidige sample, geluid heeft waargenomen.
Hierna beginnen we aan een nieuwe sample meting. We zetten de sampleBufferValue
(dus hoe vaak er geluid is waargenomen) weer op 0
. Tot slot maken we millisLast
gelijk aan millisCurrent
, zodat we opnieuw de verstreken tijd van de huidige sample kunnen berekenen.
Je kunt nu de code naar de Arduino uploaden.
Open vervolgens de seriële plotter om de gesamplede waarden van de sensor weer te geven.
De x-as (horizontaal) is de tijd as. We hebben SAMPLE_TIME
ingesteld op 10ms. Dit betekend dat dus elk horizontaal punt gelijk staat aan 10ms. Als we dus op de x-as het getal 100 zien staan (100x 10ms) is dus 1 seconde verstreken.
De y-as (verticaal) is het aantal momenten binnen 10ms dat de Arduino geluid heeft waargenomen. Dit hangt samen met hoe snel de Arduino door de loop()
kan gaan. Zo zal een 8Mhz Arduino minder metingen per seconde kunnen doen dan een 16Mhz Arduino. Het zijn dus ook geen exacte waarden, maar moeten meer relatief van elkaar worden bekeken.