From 1d7ad9daee131c758cdf95b5608f602254f10427 Mon Sep 17 00:00:00 2001 From: "Jan \"Yenya\" Kasprzak" Date: Wed, 29 Aug 2012 17:51:52 +0200 Subject: [PATCH] feedback loop with some testing code --- lights.h | 1 + pattern.c | 40 ++++++++++++++++++++++++--------- pwmled.c | 66 +++++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 78 insertions(+), 29 deletions(-) diff --git a/lights.h b/lights.h index 9e3a43b..ef176a4 100644 --- a/lights.h +++ b/lights.h @@ -39,6 +39,7 @@ void pwmled_init(); void pwmled_adc(unsigned char n, uint16_t adcval); void pwmled_set_mode(unsigned char n, unsigned char mode); unsigned char pwmled_needs_adc(unsigned char n); +unsigned char pwmled_enabled(unsigned char n); /* gpio.c */ #define GPIO_LED1 0 diff --git a/pattern.c b/pattern.c index 8552240..0691170 100644 --- a/pattern.c +++ b/pattern.c @@ -23,7 +23,11 @@ pattern_t blink_pattern[] = { }; pattern_t mode1_pattern[] = { - { 1, 0x1F }, + { 1, 0x1 }, + { 0, 0x1 }, + { 4, 0x1 }, + { 0, 0x1 }, + { 1, 0x1 }, PATTERN_END }; @@ -71,6 +75,8 @@ pattern_t pattern_num[] = { PATTERN_END }; +static unsigned char test_running; + void pattern_init() { unsigned char i; @@ -82,19 +88,37 @@ void pattern_init() led_patterns[N_PWMLEDS] = boot_pattern; led_counters[N_PWMLEDS] = boot_pattern->duration; gpio_set(GPIO_LED2, 1); + test_running = 0; } static inline pattern_t *pattern_select(unsigned char n) { + if (n < N_PWMLEDS && !pwmled_enabled(n)) + return off_pattern; // Don't mess with non-enabled LEDs + + if (n == 2) { + if (test_running) { + log_byte(0xF7); + log_flush(); + return off_pattern; + } else { + test_running = 1; + log_byte(0xF6); + return mode1_pattern; + } + } return pattern_num + sizeof(pattern_num)/sizeof(pattern_t) - - 1 - 2*(1+ambient_zone);; + - 1 - 2*(1+ambient_zone); } -static void inline led_off(unsigned char n) +static void led_set_mode(unsigned char n, unsigned char mode) { - if (n == N_PWMLEDS) { - gpio_set(GPIO_LED2, 0); + if (n < N_PWMLEDS) { + pwmled_set_mode(n, mode); + } else if (n == N_PWMLEDS) { + gpio_set(GPIO_LED2, mode); } + // TODO LED 1 } static void inline led_set_level(unsigned char n, unsigned char level) @@ -115,11 +139,7 @@ void patterns_next_tick() led_patterns[i] = pattern_select(i); } led_counters[i] = led_patterns[i]->duration; - if (led_patterns[i]->mode == 0) { - led_off(i); - } else { - led_set_level(i, led_patterns[i]->mode - 1); - } + led_set_mode(i, led_patterns[i]->mode); } led_counters[i]--; diff --git a/pwmled.c b/pwmled.c index 5c816b3..b4545e7 100644 --- a/pwmled.c +++ b/pwmled.c @@ -20,6 +20,7 @@ static unsigned char pwmled_state[N_PWMLEDS]; #define ST_ON 3 static unsigned char pwmled_mode[N_PWMLEDS]; +static unsigned char pwmled_mode_set[N_PWMLEDS]; static unsigned char pwm_probes[N_PWMLEDS]; @@ -35,8 +36,11 @@ void pwmled_init() { unsigned char i; - for (i = 0; i < N_PWMLEDS*N_PWMLED_MODES; i++) + for (i = 0; i < N_PWMLEDS*N_PWMLED_MODES; i++) { pwm_vals[i] = 0; + pwmled_mode[i] = 0; + pwmled_mode_set[i] = 0; + } for (i = 0; i < N_PWMLEDS; i++) { start_probing(i); @@ -66,6 +70,10 @@ void pwmled_set_mode(unsigned char n, unsigned char mode) if (!pwmled_enabled(n)) return; + log_byte(0xF8); + log_byte(n); + log_byte(mode); + if (mode == 0) { pwm_off(n); pwmled_state[n] = ST_OFF; @@ -73,10 +81,15 @@ void pwmled_set_mode(unsigned char n, unsigned char mode) } if (mode <= N_PWMLED_MODES) { + unsigned char pwmval; mode--; - pwm_set(n, pwm_vals[n*N_PWMLED_MODES+mode]); + pwmval = pwm_vals[n*N_PWMLED_MODES+mode]; + pwm_set(n, pwmval); + pwm_on(n); + log_byte(pwmval); pwmled_state[n] = ST_ON; pwmled_mode[n] = mode; + pwmled_mode_set[n] = 1; } } @@ -93,15 +106,16 @@ static void inline probing_adc(unsigned char n, uint16_t adcval) log_word(adcval); #endif -#if 0 - if (pwm == 0 && adcval > 0) { // non-zero voltage with zero PWM? + if (adcval > 0x100 // Too high + || (pwm == 0 && adcval > 0) // non-zero voltage with zero PWM + ) { + pwm_off(n); pwmled_state[n] = ST_DISABLED; - log_byte(n); log_byte(0xF0); + log_byte(n); log_word(adcval); return; } -#endif for (i = 0; i < N_PWMLED_MODES; i++, pwm_p++, adc_p++) { uint16_t adc = *adc_p; @@ -148,13 +162,24 @@ static void inline probing_adc(unsigned char n, uint16_t adcval) // Feedback loop static void inline on_adc(unsigned char n, uint16_t adcval) { -#if 0 - uint16_t new_pwm = led_modes[led_mode].pwmval; - uint16_t old_pwm = new_pwm; - uint16_t adc_exp = led_modes[led_mode].expected; + unsigned char mode = pwmled_mode[n]; + uint16_t adc_exp = adc_vals[n*N_PWMLED_MODES+mode]; + unsigned char *pwm_p = &pwm_vals[n*N_PWMLED_MODES+mode]; + uint16_t old_pwm = *pwm_p; + uint16_t new_pwm = old_pwm; + +#if 1 + log_byte(0xF5); + log_byte(n); + log_word(adcval); +#endif - log_word(((adcval & 0xFF) << 8) | old_pwm); + if (pwmled_mode_set[n]) { // ignore the first reading + pwmled_mode_set[n] = 0; + return; + } + // FIXME: running average? if (2*adcval > 5*adc_exp) { // >2.5x expected, lower significantly new_pwm = 2*old_pwm/3; } else if (3*adcval > 4*adc_exp) { // >1.33x expected, lower a bit @@ -163,20 +188,20 @@ static void inline on_adc(unsigned char n, uint16_t adcval) new_pwm = old_pwm + 1; } - if (new_pwm > 0x60) { // odpojeno? + // FIXME: better disconnect detection + if (new_pwm > 0x60) { // disconnected? new_pwm = 0x60; } - if (new_pwm < 2) { // zkrat? + if (new_pwm < 2) { // short-circuit? new_pwm = 2; } -set_pwm: if (new_pwm != old_pwm) { - led_modes[led_mode].pwmval = new_pwm; - OCR1D = new_pwm; + *pwm_p = new_pwm; + pwm_set(n, new_pwm); + log_byte(0xF9); + log_byte(new_pwm); } - // ADCSRA |= _BV(ADSC); -#endif } void pwmled_adc(unsigned char n, uint16_t adcval) @@ -186,6 +211,7 @@ void pwmled_adc(unsigned char n, uint16_t adcval) case ST_PROBING: probing_adc(n, adcval); +#if 1 probing = 0; for (i = 0; i < N_PWMLEDS; i++) if (pwmled_state[i] == ST_PROBING) @@ -198,12 +224,14 @@ void pwmled_adc(unsigned char n, uint16_t adcval) for (i = 0; i < N_PWMLEDS*N_PWMLED_MODES; i++) log_byte(pwm_vals[i]); log_flush(); + log_set_state(4); } +#endif return; case ST_ON: on_adc(n, adcval); return; - // WTF am I doing in this function then? + // WTF am I doing in this function then? Maybe recently switched off? } } -- 2.43.5