From 187c9157990ece22395e5c31d1822e1815fc9691 Mon Sep 17 00:00:00 2001 From: fruchti Date: Thu, 16 Jul 2020 22:43:39 +0200 Subject: [PATCH] Use integer arithmetic for light sensor --- build-number.txt | 2 +- src/animation.c | 12 ++++-------- src/animation.h | 4 ---- src/light_sensor.c | 45 ++++++++++++++++++++++++--------------------- src/light_sensor.h | 12 ++++++++---- 5 files changed, 37 insertions(+), 38 deletions(-) diff --git a/build-number.txt b/build-number.txt index 55bd0ac..35329ed 100644 --- a/build-number.txt +++ b/build-number.txt @@ -1 +1 @@ -333 +361 diff --git a/src/animation.c b/src/animation.c index 377fe82..5d5e147 100644 --- a/src/animation.c +++ b/src/animation.c @@ -276,12 +276,9 @@ LED_Colour_t Animation_GetColour(unsigned int step, unsigned int brightness) LED_Colour_t colour = Animation_ColourLUT[index]; - colour.r = ((unsigned int)colour.r * brightness) - >> ANIMATION_BRIGHTNESS_BITS; - colour.g = ((unsigned int)colour.g * brightness) - >> ANIMATION_BRIGHTNESS_BITS; - colour.b = ((unsigned int)colour.b * brightness) - >> ANIMATION_BRIGHTNESS_BITS; + colour.r = ((unsigned int)colour.r * brightness) >> LIGHTSENSOR_BITS; + colour.g = ((unsigned int)colour.g * brightness) >> LIGHTSENSOR_BITS; + colour.b = ((unsigned int)colour.b * brightness) >> LIGHTSENSOR_BITS; return colour; } @@ -305,7 +302,6 @@ void Animation_Poll(void) return; } LED_FrameFlag = false; - Animation_DrawGradient(60000, 50000, - ANIMATION_MAX_BRIGHTNESS * LightSensor_RelativeBrightness); + Animation_DrawGradient(60000, 50000, LightSensor_RelativeBrightness); LED_Commit(); } \ No newline at end of file diff --git a/src/animation.h b/src/animation.h index 7b28abb..036115d 100644 --- a/src/animation.h +++ b/src/animation.h @@ -3,10 +3,6 @@ #include "led.h" #define ANIMATION_STEPS 65535 -#define ANIMATION_BRIGHTNESS_BITS \ - 16 -#define ANIMATION_MAX_BRIGHTNESS \ - (1 << ANIMATION_BRIGHTNESS_BITS) extern const unsigned int Animation_LEDOrder[LED_COUNT]; diff --git a/src/light_sensor.c b/src/light_sensor.c index 6f0d8e1..0b10abe 100644 --- a/src/light_sensor.c +++ b/src/light_sensor.c @@ -4,13 +4,13 @@ volatile unsigned int LightSensor_Measurement; volatile bool LightSensor_NewMeasurement = false; // Rolling average of the brightness measurement -float LightSensor_AbsoluteBrightness = 0.5f; +unsigned int LightSensor_AbsoluteBrightness = LIGHTSENSOR_MAX / 2; // Maximum and minimum encountered so far -float LightSensor_MinimumBrightness = 1.0f; -float LightSensor_MaximumBrightness = 0.0f; +unsigned int LightSensor_MinimumBrightness = LIGHTSENSOR_MAX; +unsigned int LightSensor_MaximumBrightness = 0; -float LightSensor_RelativeBrightness; +int LightSensor_RelativeBrightness; static void LightSensor_Measure(void) { @@ -66,35 +66,38 @@ void LightSensor_Poll(void) { unsigned int measurement = LightSensor_Measurement; LightSensor_NewMeasurement = false; - float brightness = 65535.0f / measurement; - LightSensor_AbsoluteBrightness = LIGHTSENSOR_LAMBDA * LightSensor_AbsoluteBrightness - + (1.0f - LIGHTSENSOR_LAMBDA) * brightness; + unsigned int brightness = ((1 << 31) + / (measurement + 1)) >> (31 - 16); + // LightSensor_AbsoluteBrightness = LIGHTSENSOR_LAMBDA * LightSensor_AbsoluteBrightness + // + (1.0f - LIGHTSENSOR_LAMBDA) * brightness; + LightSensor_AbsoluteBrightness -= LightSensor_AbsoluteBrightness >> LIGHTSENSOR_LAMBDA_BITS; + LightSensor_AbsoluteBrightness += brightness >> LIGHTSENSOR_LAMBDA_BITS; - if(LightSensor_AbsoluteBrightness < LightSensor_MinimumBrightness) + if(brightness < LightSensor_MinimumBrightness) { - LightSensor_MinimumBrightness = LightSensor_AbsoluteBrightness; + LightSensor_MinimumBrightness = brightness; } - if(LightSensor_AbsoluteBrightness > LightSensor_MaximumBrightness) + if(brightness > LightSensor_MaximumBrightness) { - LightSensor_MaximumBrightness = LightSensor_AbsoluteBrightness; + LightSensor_MaximumBrightness = brightness; } // Scale and saturate to get relative brightness value - float range = LightSensor_MaximumBrightness + int range = LightSensor_MaximumBrightness - LightSensor_MinimumBrightness; - float low = LightSensor_MinimumBrightness - + range * LIGHTSENSOR_LOW_BOUND; - float high = LightSensor_MinimumBrightness - + range * LIGHTSENSOR_HIGH_BOUND; + int low = LightSensor_MinimumBrightness + + LIGHTSENSOR_LOW_BOUND * range / LIGHTSENSOR_MAX; + int high = LightSensor_MinimumBrightness + + LIGHTSENSOR_HIGH_BOUND * range / LIGHTSENSOR_MAX; LightSensor_RelativeBrightness = (LightSensor_AbsoluteBrightness - low) - / (high - low); - if(LightSensor_RelativeBrightness < 0.0f) + * LIGHTSENSOR_MAX / (high - low); + if(LightSensor_RelativeBrightness < 0) { - LightSensor_RelativeBrightness = 0.0f; + LightSensor_RelativeBrightness = 0; } - if(LightSensor_RelativeBrightness > 1.0f) + if(LightSensor_RelativeBrightness > LIGHTSENSOR_MAX) { - LightSensor_RelativeBrightness = 1.0f; + LightSensor_RelativeBrightness = LIGHTSENSOR_MAX; } } } diff --git a/src/light_sensor.h b/src/light_sensor.h index 4ae31cc..bc99ee2 100644 --- a/src/light_sensor.h +++ b/src/light_sensor.h @@ -8,15 +8,19 @@ // ADC polling interval in milliseconds #define LIGHTSENSOR_INTERVAL 250 +// Resolution of the brightness output +#define LIGHTSENSOR_BITS 12 +#define LIGHTSENSOR_MAX (1 << LIGHTSENSOR_BITS) + // 'Forgetting factor' of the rolling brightness average -#define LIGHTSENSOR_LAMBDA 0.9f +#define LIGHTSENSOR_LAMBDA_BITS 4 // Bounds for converting absolute to relative brightness: Consider everything // near the minimum or maximum 0.0 or 1.0, respectively -#define LIGHTSENSOR_LOW_BOUND 0.005f -#define LIGHTSENSOR_HIGH_BOUND 0.9f +#define LIGHTSENSOR_LOW_BOUND ((unsigned int)(0.005 * LIGHTSENSOR_MAX)) +#define LIGHTSENSOR_HIGH_BOUND ((unsigned int)(0.9 * LIGHTSENSOR_MAX)) -extern float LightSensor_RelativeBrightness; +extern int LightSensor_RelativeBrightness; void LightSensor_Init(void); void LightSensor_Poll(void);