- 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 new_zone, user_zone;
+ unsigned char byte_fast, byte_slow, drop;
+ uint16_t a_10bit;
+
+ // running avg - shorter timespan
+ ambient_fast += adcval - (ambient_fast >> AMBIENT_FAST_SHIFT);
+
+ // running avg - longer timespan
+ a_10bit = ambient_fast >> (AMBIENT_FAST_SHIFT + AMBIENT_ADC_SHIFT);
+ ambient_slow += a_10bit - (ambient_slow >> AMBIENT_SLOW_SHIFT);
+
+ // ambient zones are governed by shorter timespan by default
+ new_zone = val_to_zone(a_10bit);
+
+ if (new_zone > 1 && (
+ new_zone == ambient_zone-1 || new_zone == ambient_zone+1)) {
+ // but change to the neighbouring zone is governed by _slow,
+ // except to the darkest zone, where we want fast reaction.
+ new_zone = val_to_zone(ambient_slow >> AMBIENT_SLOW_SHIFT);
+ }
+
+ // user_param ambient zone override
+ if ((user_zone = get_user_param(0)) > 0)
+ new_zone = user_zone - 1;
+
+ // TODO: maybe use these values instead of 10-bit?
+ byte_fast = a_10bit >> 2;
+ byte_slow = ambient_slow >> (AMBIENT_SLOW_SHIFT + 2);
+
+ if (byte_slow > byte_fast) {
+ drop = byte_slow - byte_fast;
+ if (drop > ambient_drop)
+ ambient_drop = drop;
+ }
+
+ if (ambient_min > byte_fast)
+ ambient_min = byte_fast;
+
+ if (ambient_max < byte_fast)
+ ambient_max = byte_fast;
+
+ if (new_zone != ambient_zone) {
+ ambient_zone = new_zone;
+#if 0
+ log_byte(0xab);
+ log_byte(ambient_zone);
+ log_word(adcval);
+ log_flush();
+#endif
+ ambient_zone_changed();