]> www.fi.muni.cz Git - bike-lights.git/commitdiff
working feedback loop
authorJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 14 Jun 2012 21:07:53 +0000 (23:07 +0200)
committerJan "Yenya" Kasprzak <kas@fi.muni.cz>
Thu, 14 Jun 2012 21:07:53 +0000 (23:07 +0200)
lights.c

index 635b24996f871fcc3fdc64451b1dd212f9806422..22bfc94ba9f1bd131ad6cc07c86daa761ba69fc9 100644 (file)
--- a/lights.c
+++ b/lights.c
@@ -5,8 +5,10 @@
 #include <avr/interrupt.h>
 
 volatile uint16_t adcval;
-unsigned char pwmval = 0x28;
-uint16_t pwmints = 0;
+unsigned char pwmval = 0x10;
+volatile uint16_t adc_exp = 0xd0;
+unsigned char led_is_on = 0;
+volatile unsigned char adccount = 0;
 
 volatile struct
 {
@@ -19,11 +21,14 @@ intflags;
 static void inline led_on()
 {
         DDRB |= _BV( PB5 );
+       led_is_on = 1;
 }
 
 static void inline led_off()
 {
+       led_is_on = 0;
         DDRB &= ~_BV( PB5 );
+//        ADCSRA &= ~(_BV(ADIE) | _BV(ADIF));
 }
 
 /* ------------ Logging/Debugging ----------- */
@@ -35,9 +40,11 @@ static void inline debug_setstate(unsigned char val)
        eeprom_write_byte(&debug_state, val);
 }
 
-#define LOG_BUFFER 192
+#define LOG_BUFFER 64
 uint16_t log_buffer[LOG_BUFFER] EEMEM;
-uint16_t log_buffer_count;
+unsigned char log_buffer_count;
+uint16_t log_buffer2[LOG_BUFFER];
+volatile unsigned char stop = 0;
 
 static void inline init_log()
 {
@@ -46,26 +53,32 @@ static void inline init_log()
 }
 
 static void log_word(uint16_t word) {
-       if (log_buffer_count == LOG_BUFFER) {
-                debug_setstate(0x42);
-               log_buffer_count++;
-       }
        if (log_buffer_count >= LOG_BUFFER)
                return;
        
-       eeprom_write_word(&log_buffer[log_buffer_count], word);
+       // eeprom_write_word(&log_buffer[log_buffer_count], word);
+       log_buffer2[log_buffer_count] = word;
        log_buffer_count++;
+
+       if (log_buffer_count == LOG_BUFFER) {
+               unsigned char i;
+               for (i=0; i < LOG_BUFFER; i++) {
+                       eeprom_write_word(&log_buffer[i],
+                               log_buffer2[i]);
+               }
+               debug_setstate(0x42);
+       }
 }
 
 /* ------------ Timer ----------- */
 
-uint16_t clock = 0;
+volatile uint16_t clock = 0;
 
 static void inline init_tmr()
 {
        TCCR0A = _BV(WGM00);
        TCCR0B = _BV(CS02) | _BV(CS00); // 1 kHz
-       OCR0A = 10; // 100 Hz
+       OCR0A = 12; // 100 Hz
        TIMSK |= _BV(OCIE0A);
        DDRA |= _BV( PA0 );
 
@@ -74,21 +87,38 @@ static void inline init_tmr()
 
 static void inline tmr_handler()
 {
-       unsigned char c = clock & 0x7F;
-       ++clock;
+       unsigned char c = clock & 0x1F;
+       unsigned char c1 = clock & 0xFF;
 
+       ++clock;
+#if 0
        if (c == 10 || c == 30) 
                led_on();
 
        if (c == 20 || c == 40)
                led_off();
+#endif
+
+       if (c == 0x02 || c == 0x08)
+               led_on();
+       if (c == 0x05 || c == 0x0b)
+               led_off();
 
-       log_word(adcval);
-       if (adcval != 0xFFEE) {
+       if ((clock & 0x7F) == 0x1F) {
+               if (c1 < 0x80) {
+                       adc_exp = 0xc0;
+               } else {
+                       adc_exp = 0x20;
+               }
+       }
+       ADCSRA |= _BV(ADSC);
+#if 0
+       if (led_is_on && adcval != 0xFFEE) {
                adcval = 0xFFEE;
 
-               ADCSRA |= _BV(ADIE) | _BV(ADSC);
+               ADCSRA |= _BV(ADIF) | _BV(ADIE) | _BV(ADSC);
        }
+#endif
 }
 
 ISR(TIMER0_COMPA_vect)
@@ -110,27 +140,28 @@ static void inline init_pwm()
        TCCR1C = _BV(COM1D0) | _BV(COM1D1) | _BV(PWM1D);
        TCCR1A = _BV(COM1A0) | _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(PWM1A) | _BV(PWM1B);
        // TCCR1B = 0x80| _BV(CS13) | _BV(CS11);
-       TCCR1B = 0x80 | _BV(CS10);
-       OCR1C = 0xFF;
+       TCCR1B = _BV(7)                         // PWM1X: PWM inversion mode
+               | _BV(CS10)                     // no clock prescaling
+               ;
+       OCR1C = 0xFF;                           // TOP value
        OCR1D = OCR1B = OCR1A = pwmval;
-       TCNT1 = 0;
-       DDRB |= _BV( PB5 );
+       // OCR1D = 0;
+       // DDRB |= _BV( PB5 );
        PORTB &= ~(_BV( PB5 ) | _BV( PB1 ) | _BV( PB3 ));
 
-       led_off();
+       // led_off();
        // TIMSK |= _BV(TOIE1);
 }
 
 #if 0
 static void inline pwm_handler()
 {
-       TCNT1 = 0;
-       OCR1D = pwmval;
+       // TIMSK &= ~_BV(TOIE1);
+       // OCR1D = pwmval;
 }
 
 ISR(TIMER1_OVF_vect)
 {
-       TIMSK &= ~_BV(TOIE1);
        pwm_handler();
 }
 #endif
@@ -139,72 +170,60 @@ ISR(TIMER1_OVF_vect)
 
 static void inline init_adc()
 {
-       ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADPS1) | _BV(ADPS0);
-       ADMUX = _BV(REFS1) | _BV(MUX0);
+       ADCSRA = _BV(ADEN)                      // enable
+               | _BV(ADPS1) | _BV(ADPS0)       // CLK/8 = 125 kHz
+               // | _BV(ADPS2)                 // CLK/16 = 62.5 kHz
+               ;
+       ADMUX = _BV(REFS1)                      // 1.1V internal reference
+               | _BV(MUX4)|_BV(MUX3)   // port ADC5-6, gain 1
+               ;
        // ADCSRB = _BV(REFS2); 
-       DIDR0 = _BV(ADC1D) | _BV(AREFD);
+       ADCSRB |= _BV(GSEL); 
+       // Disable digital input on all bits used by ADC
+       DIDR0 = _BV(ADC5D)|_BV(ADC6D) | _BV(AREFD);
+       ADCSRA |= _BV(ADIE);
 }
 
 static void inline adc_handler()
 {
-       static unsigned char last_pwmval = 0;
-       static unsigned char counter = 0;
-       uint16_t tmp = pwmval;
-       static uint16_t discard = 5;
-
+       uint16_t new_pwm = pwmval;
+       uint16_t old_pwm = pwmval;
+       uint16_t old_adc = adcval;
        adcval = ADCW;
-       ADCSRA &= ~_BV(ADIE);         /* disable ADC interrupt */
-#if 0
-       if (--discard > 0)
-               goto out;
-
-       if (adcval > 0x300)
-               tmp = 3*tmp/4;
-       else if (adcval > 0x280)
-               tmp = 7*tmp/8;
-       else if (adcval > 0x201)
-               tmp--;
-       else if (adcval < 0x100)
-               tmp = 5*tmp/4;
-       else if (adcval < 0x180)
-               tmp = 9*tmp/8;
-       else if (adcval < 0x1ff)
-               tmp++;
-
-       if (tmp > 0xFF)
-               tmp = 0xFF;
-       if (tmp == 0)
-               tmp = 1;
-
-       counter++;
-       if ((last_pwmval > tmp && last_pwmval - tmp > 10)
-               || (last_pwmval < tmp && tmp - last_pwmval > 10)
-               || (counter > 2)) {
-               counter = 0;
-       
-               if (rv_count < BUFFER-1) {
-                       eeprom_write_word(&readval[rv_count++], adcval);
-                       eeprom_write_word(&readval[rv_count++], pwmval);
-                       if (rv_count >= BUFFER)
-                               eeprom_write_byte(&debug, 42);
-               }
-       }
+       adccount++;
 
-       last_pwmval = pwmval;
-       pwmval = tmp;
+       // log_word(((adcval & 0x3FC) << 6) | pwmval);
+       log_word(((adcval & 0xFF) << 8) | pwmval);
 
-       if (pwmval != last_pwmval) {
-               TIMSK |= _BV(TOIE1);
-               
-               discard = 1000;
-       } else {
-               discard = 0;
+       if (!led_is_on)
+               return;
+       // adcval = (adcval + 3*old_adc)/4;
+
+       // ADCSRA &= ~(_BV(ADIE) | _BV(ADIF));
+
+       if (adcval < 1) {
+               adcval = 1;
+       } else if (adcval > adc_exp) {
+               new_pwm = old_pwm*adc_exp/adcval;
+       } else if (adcval < adc_exp && 2 * adcval > adc_exp) {
+               new_pwm = old_pwm*adc_exp/adcval;
+       } else if (adcval < adc_exp) {
+               new_pwm = 2 * old_pwm;
        }
 
-out:
-       //TIMSK |= _BV(TOIE1);
-       ADCSRA |= _BV(ADIE) | _BV(ADSC);
-#endif
+       new_pwm = (3*old_pwm + new_pwm) / 4;
+       if (new_pwm > 0x60) { // odpojeno?
+               new_pwm = 0x60;
+       }
+       if (new_pwm < 2) { // zkrat?
+               new_pwm = 2;
+       }
+
+       // if (new_pwm < 15*old_pwm/16 || new_pwm > 17*old_pwm/16) {
+               pwmval = new_pwm;
+               OCR1D = pwmval;
+       // }
+       // ADCSRA |= _BV(ADSC);
 }
 
 ISR(ADC_vect)
@@ -212,29 +231,8 @@ ISR(ADC_vect)
        adc_handler();
 }
 
-#if 0
-       if (--pcount == 0) {
-               ppos++;
-               pcount = pattern[ppos].length;
-               if (!pcount) {
-                       ppos = 0;
-                       pcount = pattern[ppos].length;
-               }
-               if (pattern[ppos].intensity) {
-                       PORTA |= _BV(PA0);
-               } else {
-                       PORTA &= ~_BV(PA0);
-               }
-       }
-#endif
-
 int main(void)
 {
-       char seen = 0;
-       char pcount, ppos;
-       unsigned char adcidx = 0;
-       uint16_t adcvals[16];
-
        init_log();
 
        init_pwm();
@@ -245,18 +243,14 @@ int main(void)
 
        sei();
        while (1)
-               ; //sleep_mode();
-#if 0
-               if (!seen) {
-                       seen = 1;
-                       eeprom_write_byte(&debug, 2);
-               }
-#endif
+               ;// sleep_mode();
 
+#if 0
     DDRA |= _BV( PA0 );
     while( 1 ) { 
         PORTA |=  _BV( PA0 );
         _delay_ms(200);
         PORTA &=~ _BV( PA0 );
     }
+#endif
 }