Automatisch dimmen als het donker wordt
Het project ligt even een beetje stil, maar ik heb in de tussentijd wel een kleine uitbreiding gemaakt zodat je ‘s nachts niet wordt verblind door een zee aan licht, maar dat je tegelijk overdag de klok ook nog kan aflezen.
Met een fotodiode meet ik het omgevingslicht en dankzij de in de Arduino ingebouwde analoog-digitaalomzetter is het weer een poepsimpel circuitje geworden:
De analoge poort A0
lees je eenvoudig uit met de functie analogRead(A0)
. De waarde uit de analoge poort wordt
omgezet naar een 10-bit integer, dus tussen 0 en 1024. Omdat setBrightness
een waarde tussen 0 en 255 wil, delen we
die door 4 en om te voorkomen dat het licht helemaal uitgaat in het donker zetten we er een minimum op.
void updateBrightness()
{
int brightnessReading = analogRead(A0) / 4;
pixels.setBrightness(max(brightnessReading, 1));
}
Dit kan echter — zoals bij veel regelsystemen — leiden tot hysterese, waarbij het licht feller gaat branden omdat het licht wegvalt, maar doordat het licht feller gaat branden het weer lichter wordt en de helderheid bij de volgende keer dat de sensor wordt uitgelezen weer naar beneden wordt bijgesteld, waarna het hele circus opnieuw begint. Dit kunnen we voorkomen door de helderheid afhankelijk te maken van een langere periode.
Hieronder slaan we de ingelezen waarde tijdelijk op in een circulaire buffer van lengte 10, om vervolgens het gemiddelde
aan setBrightness
te voeren. Het voordeel in het gebruik van zo’n type buffer is dat je waardes erin kan blijven
duwen (push()
) en als hij vol is valt de oudste waarde eruit. Omdat ik een lopend gemiddelde wil bepalen, haal ik die
oudste waarde er zelf uit (shift()
) en trek die van het gemiddelde af.
#include <CircularBuffer.h>
CircularBuffer<int, 10> brightnessReadings;
int brightnessAverage = 0;
void updateBrightness()
{
int brightnessReading = analogRead(A0) / 4;
brightnessAverage += brightnessReading;
if (brightnessReadings.isFull()) {
brightnessAverage -= brightnessReadings.shift();
}
brightnessReadings.push(brightnessReading);
pixels.setBrightness(max(brightnessAverage / brightnessReadings.size(), 1));
}
De waarde die uiteindelijk naar setBrightness
gaat is het gemiddelde van de 10 laatste
waarden. Een plotse verandering in helderheid wordt daardoor uitgesmeerd over 100 milliseconden (de loop()
functie
heeft een delay(10)
die ervoor zorgt dat die aan het eind van elk rondje 10 milliseconden wacht) en hysterese wordt
voorkomen.
Webmentions
Heb je een reactie op dit artikel geschreven? Stuur me een webmention! Het kan een paar dagen duren voordat je reactie hier verschijnt.