diff --git a/wordclock/lightlevelmapping.m b/wordclock/lightlevelmapping.m index 8174086..85282f4 100644 --- a/wordclock/lightlevelmapping.m +++ b/wordclock/lightlevelmapping.m @@ -1,4 +1,39 @@ function lightlevelmapping() +MINBRIGHTNESS = 1; +MAXBRIGHTNESS = 10; + +LIGHTSENSOR_BOTTOM = 0; +LIGHTSENSOR_TOP = 150; + +x = [LIGHTSENSOR_BOTTOM - 10:LIGHTSENSOR_TOP + 10]; +b = zeros(size(9)); + +LIGHTSENSOR_ALPHA1 = 0.02; +LIGHTSENSOR_ALPHA2 = 0.20; + +a = LIGHTSENSOR_ALPHA1 * LIGHTSENSOR_TOP / log(LIGHTSENSOR_ALPHA2 / ... + LIGHTSENSOR_ALPHA1); +b = LIGHTSENSOR_ALPHA1 / a; +c = MINBRIGHTNESS - a; + +y = a * exp(b*x) + c; +y_ = round(y); + +[x; y_] + +figure +plot(x, y, x, y_); +A = axis; +A(1) = LIGHTSENSOR_BOTTOM - 2; +A(2) = LIGHTSENSOR_TOP - 2; +A(3) = MINBRIGHTNESS - 2; +A(4) = MAXBRIGHTNESS + 2; +axis(A); +grid on + +return + +function lightlevelmapping_old() MINBRIGHTNESS = 0; MAXBRIGHTNESS = 10; diff --git a/wordclock/wordclock.ino b/wordclock/wordclock.ino index 3f5b92a..d4a6ac7 100644 --- a/wordclock/wordclock.ino +++ b/wordclock/wordclock.ino @@ -75,7 +75,12 @@ void SWversion(void); #define LIGHTSENSOR_BOTTOM 0 // top of light sensor (ambient light values at or higher than this level will // be mapped to MAXBRIGHTNESS) -#define LIGHTSENSOR_TOP 900 +#define LIGHTSENSOR_TOP 150 +// slope of mapping function at bottom +#define LIGHTSENSOR_ALPHA1 0.02 +// slope of mapping function at top +#define LIGHTSENSOR_ALPHA2 0.20 + // weight for exponential decaying averaging (actual weigth is 2 ^ LIGHTSENSOR_WEIGHT) #define LIGHTSENSOR_WEIGHT 4 // base of exponential mapping (must be > 1) @@ -87,7 +92,7 @@ void SWversion(void); // start MAXBRIGHTNESS at DAYLIGHTHOUR (7 am) #define DAYLIGHTHOUR 7 // NIGHT Brightness setting 0 = off, N_PWM_STEPS - 1 = full -#define MINBRIGHTNESS 2 +#define MINBRIGHTNESS 1 // start MINBRIGHTNESS at NIGHTLIGHTHOUR (7 pm) #define NIGHTLIGHTHOUR 19 @@ -180,6 +185,9 @@ void setup() { int n; + // a, b, c and e are needed to compute lookup table for ambient light sensor + float a, b, c, e; + // initialise the hardware // initialize the appropriate pins as outputs: pinMode(LEDClockPin, OUTPUT); @@ -245,6 +253,12 @@ void setup() } // compute ambient light level to brightness level mapping + a = LIGHTSENSOR_ALPHA1 * LIGHTSENSOR_TOP / log(LIGHTSENSOR_ALPHA2 / + LIGHTSENSOR_ALPHA1); + b = LIGHTSENSOR_ALPHA1 / a; + c = MINBRIGHTNESS - a; + e = 2.718281828459045297; + for (n = 0; n < sizeof(ambient_light_to_brightness); n++) { if (n <= LIGHTSENSOR_BOTTOM) @@ -254,18 +268,15 @@ void setup() else { ambient_light_to_brightness[n] = - round( pow((double) LIGHTSENSOR_BASE, ( - (double) brightness_per_unit_light * ((double) n - (double) - LIGHTSENSOR_BOTTOM) / (double) (1 << LIGHTSENSOR_SCALE))) / pow((double) - LIGHTSENSOR_BASE, (double) (MAXBRIGHTNESS - (double) MINBRIGHTNESS)) * - ((double) MAXBRIGHTNESS - (double) MINBRIGHTNESS) + (double) MINBRIGHTNESS ); - /* Serial.print(n); - Serial.print(": "); - Serial.println(ambient_light_to_brightness[n], DEC); */ + round(((float) a) * pow(e, ((float) b) * + ((float) n)) + (float) c); + if (ambient_light_to_brightness[n] < MINBRIGHTNESS) + ambient_light_to_brightness[n] = MINBRIGHTNESS; + if (ambient_light_to_brightness[n] > MAXBRIGHTNESS) + ambient_light_to_brightness[n] = MAXBRIGHTNESS; } } - // determine whether we are running on old or new hardware // old hardware tied the push buttons to ground using 4k7 resistors // and relied on the buttons to pull them high