Use integer arithmetic for light sensor

This commit is contained in:
fruchti 2020-07-16 22:43:39 +02:00
parent 3121557afd
commit 187c915799
5 changed files with 37 additions and 38 deletions

View file

@ -1 +1 @@
333 361

View file

@ -276,12 +276,9 @@ LED_Colour_t Animation_GetColour(unsigned int step, unsigned int brightness)
LED_Colour_t colour = Animation_ColourLUT[index]; LED_Colour_t colour = Animation_ColourLUT[index];
colour.r = ((unsigned int)colour.r * brightness) colour.r = ((unsigned int)colour.r * brightness) >> LIGHTSENSOR_BITS;
>> ANIMATION_BRIGHTNESS_BITS; colour.g = ((unsigned int)colour.g * brightness) >> LIGHTSENSOR_BITS;
colour.g = ((unsigned int)colour.g * brightness) colour.b = ((unsigned int)colour.b * brightness) >> LIGHTSENSOR_BITS;
>> ANIMATION_BRIGHTNESS_BITS;
colour.b = ((unsigned int)colour.b * brightness)
>> ANIMATION_BRIGHTNESS_BITS;
return colour; return colour;
} }
@ -305,7 +302,6 @@ void Animation_Poll(void)
return; return;
} }
LED_FrameFlag = false; LED_FrameFlag = false;
Animation_DrawGradient(60000, 50000, Animation_DrawGradient(60000, 50000, LightSensor_RelativeBrightness);
ANIMATION_MAX_BRIGHTNESS * LightSensor_RelativeBrightness);
LED_Commit(); LED_Commit();
} }

View file

@ -3,10 +3,6 @@
#include "led.h" #include "led.h"
#define ANIMATION_STEPS 65535 #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]; extern const unsigned int Animation_LEDOrder[LED_COUNT];

View file

@ -4,13 +4,13 @@ volatile unsigned int LightSensor_Measurement;
volatile bool LightSensor_NewMeasurement = false; volatile bool LightSensor_NewMeasurement = false;
// Rolling average of the brightness measurement // Rolling average of the brightness measurement
float LightSensor_AbsoluteBrightness = 0.5f; unsigned int LightSensor_AbsoluteBrightness = LIGHTSENSOR_MAX / 2;
// Maximum and minimum encountered so far // Maximum and minimum encountered so far
float LightSensor_MinimumBrightness = 1.0f; unsigned int LightSensor_MinimumBrightness = LIGHTSENSOR_MAX;
float LightSensor_MaximumBrightness = 0.0f; unsigned int LightSensor_MaximumBrightness = 0;
float LightSensor_RelativeBrightness; int LightSensor_RelativeBrightness;
static void LightSensor_Measure(void) static void LightSensor_Measure(void)
{ {
@ -66,35 +66,38 @@ void LightSensor_Poll(void)
{ {
unsigned int measurement = LightSensor_Measurement; unsigned int measurement = LightSensor_Measurement;
LightSensor_NewMeasurement = false; LightSensor_NewMeasurement = false;
float brightness = 65535.0f / measurement; unsigned int brightness = ((1 << 31)
LightSensor_AbsoluteBrightness = LIGHTSENSOR_LAMBDA * LightSensor_AbsoluteBrightness / (measurement + 1)) >> (31 - 16);
+ (1.0f - LIGHTSENSOR_LAMBDA) * brightness; // 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 // Scale and saturate to get relative brightness value
float range = LightSensor_MaximumBrightness int range = LightSensor_MaximumBrightness
- LightSensor_MinimumBrightness; - LightSensor_MinimumBrightness;
float low = LightSensor_MinimumBrightness int low = LightSensor_MinimumBrightness
+ range * LIGHTSENSOR_LOW_BOUND; + LIGHTSENSOR_LOW_BOUND * range / LIGHTSENSOR_MAX;
float high = LightSensor_MinimumBrightness int high = LightSensor_MinimumBrightness
+ range * LIGHTSENSOR_HIGH_BOUND; + LIGHTSENSOR_HIGH_BOUND * range / LIGHTSENSOR_MAX;
LightSensor_RelativeBrightness = (LightSensor_AbsoluteBrightness - low) LightSensor_RelativeBrightness = (LightSensor_AbsoluteBrightness - low)
/ (high - low); * LIGHTSENSOR_MAX / (high - low);
if(LightSensor_RelativeBrightness < 0.0f) 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;
} }
} }
} }

View file

@ -8,15 +8,19 @@
// ADC polling interval in milliseconds // ADC polling interval in milliseconds
#define LIGHTSENSOR_INTERVAL 250 #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 // '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 // Bounds for converting absolute to relative brightness: Consider everything
// near the minimum or maximum 0.0 or 1.0, respectively // near the minimum or maximum 0.0 or 1.0, respectively
#define LIGHTSENSOR_LOW_BOUND 0.005f #define LIGHTSENSOR_LOW_BOUND ((unsigned int)(0.005 * LIGHTSENSOR_MAX))
#define LIGHTSENSOR_HIGH_BOUND 0.9f #define LIGHTSENSOR_HIGH_BOUND ((unsigned int)(0.9 * LIGHTSENSOR_MAX))
extern float LightSensor_RelativeBrightness; extern int LightSensor_RelativeBrightness;
void LightSensor_Init(void); void LightSensor_Init(void);
void LightSensor_Poll(void); void LightSensor_Poll(void);