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];
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();
}

View file

@ -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];

View file

@ -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;
}
}
}

View file

@ -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);