static uint16_t ambient_val;
volatile unsigned char ambient_zone;
-static unsigned char ambient_zone_set;
-static uint16_t ambient_zones[] = {
- 0x0c00, 0x0d00, 0x1000, 0x1800, 0x2800, 0x2f80, 0xffff
+/* My photodiode reads 0x00C5 .. 0x033B */
+typedef struct {
+ uint16_t lo, hi;
+} ambient_zone_t;
+
+/*
+ * Note: these have to be sorted, starting with 0, ending with 0xFFFF
+ * and having small overlaps in order to provide a bit of hysteresis.
+ */
+static ambient_zone_t ambient_zones[] = {
+ { 0x0000, 0x3120 }, // dark
+ { 0x30f0, 0x5000 },
+ { 0x4c00, 0x8000 },
+ { 0x7800, 0xffff }
};
#define N_AMBIENT_ZONES (sizeof(ambient_zones)/sizeof(ambient_zones[0]))
void init_ambient()
{
ambient_val = 0;
- ambient_zone = 0;
- ambient_zone_set = 0;
+ ambient_zone = 1;
}
void ambient_zone_changed()
{
+#if 1
log_byte(0xab);
log_byte(ambient_zone);
log_word(ambient_val);
log_flush();
+#endif
- pattern_reload();
+ // led_set_pattern(N_PWMLEDS, status_led_pattern_select());
+ // led_set_pattern(N_PWMLEDS+1, illumination_led_pattern_select());
+ // pattern_reload();
}
void ambient_adc(uint16_t adcval)
{
- unsigned char newzone;
-
- if (!ambient_zone_set)
- ambient_val = adcval << 4;
- else // running sum
- ambient_val += adcval - (ambient_val >> 4);
-
- newzone = 0;
- while (newzone < N_AMBIENT_ZONES-1
- && ambient_zones[newzone] < ambient_val)
- newzone++;
-
- // TODO: implement hysteresis?
- if (!ambient_zone_set || newzone != ambient_zone) {
- ambient_zone = newzone;
- ambient_zone_set = 1;
- // ambient_zone_changed();
+ unsigned char old_zone = ambient_zone;
+
+ ambient_val += adcval - (ambient_val >> 6);
+
+ while (ambient_zones[ambient_zone].lo > ambient_val)
+ ambient_zone--;
+
+ while (ambient_zones[ambient_zone].hi < ambient_val)
+ ambient_zone++;
+
+#if 0
+ if (old_zone != ambient_zone) {
+ log_byte(0xab);
+ log_byte(ambient_zone);
+ log_word(adcval);
+ log_flush();
}
+ // ambient_zone_changed();
+#endif
}