Gebruik deze schakeling maar niet ;-) zie discussie hieronder
Ik post dit schema en deze (rudimentaire) code omdat het me alleszins meevalt hoe goed dit werkt. Ik denk dat meer mensen hier wel iets aan kunnen hebben. Het is een LC-filter buckconverter (in feite een gereduceerde vorm van een buckconverter) die het vermogen door de belasting regelt. Ik had dit nodig omdat ik verder niks had liggen aan LED-drivers en een 4W 6V LED moest laten branden op 12V. Dit is het voorlicht van mijn ligfiets, en in de ligfiets heb ik 11.1-12.6V (LiPo-accu) en 5V (uit een grote 7805) beschikbaar. Het voorlicht moet altijd op vol vermogen kunnen branden, ook als de accu bijna leeg is en ook als het ofwel vriest, ofwel loeiheet is (-10 tot +40 ziet mijn fiets voorbij komen). Weerstanden gebruiken voor de LED is geen optie, in de kou bij een lege batterij zakt de lichtopbrengst dan flink in. Een vaste PWM-duty cycle is ook geen optie, LEDs zijn hoogst nonlineair dus het verschil in lichtopbrengst gaat dan al helemaal mis. Het moet dus iets actief geregelds zijn. Dat is het volgende:

Met de bijbehorende AVR-GCC code:
[knip]
Ik post dit schema en deze (rudimentaire) code omdat het me alleszins meevalt hoe goed dit werkt. Ik denk dat meer mensen hier wel iets aan kunnen hebben. Het is een LC-filter buckconverter (in feite een gereduceerde vorm van een buckconverter) die het vermogen door de belasting regelt. Ik had dit nodig omdat ik verder niks had liggen aan LED-drivers en een 4W 6V LED moest laten branden op 12V. Dit is het voorlicht van mijn ligfiets, en in de ligfiets heb ik 11.1-12.6V (LiPo-accu) en 5V (uit een grote 7805) beschikbaar. Het voorlicht moet altijd op vol vermogen kunnen branden, ook als de accu bijna leeg is en ook als het ofwel vriest, ofwel loeiheet is (-10 tot +40 ziet mijn fiets voorbij komen). Weerstanden gebruiken voor de LED is geen optie, in de kou bij een lege batterij zakt de lichtopbrengst dan flink in. Een vaste PWM-duty cycle is ook geen optie, LEDs zijn hoogst nonlineair dus het verschil in lichtopbrengst gaat dan al helemaal mis. Het moet dus iets actief geregelds zijn. Dat is het volgende:

Met de bijbehorende AVR-GCC code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
| #include <avr/io.h> #include <stdio.h> int ADC_read(char input) { int OUT; ADMUX = (0<<REFS0) | (0x07&input); // VCC ref and ADCx ADCSRA |= (1 << ADIF) | (1<<ADSC); // Clear ADIF and start single conversion while(!(ADCSRA & (1 << ADIF))); // wait for conversion done, ADIF flag active OUT = ADCL; // read out ADCL register OUT += (ADCH << 8); // read out ADCH register //return ADC; return OUT; } void Init_ADC( void ) { ADMUX = 2; // VCC voltager ref, ADC2 (PB4) as default input ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);// Enable ADC, ADC prescaler /64 ADCSRA |= (1<<ADSC); // Start convertion while (ADCSRA & (1<<ADSC)); // Wait for conversion to complete ADCSRA = ADCSRA; // Clear ADC interrupt flag } int curval; int voltval; int power; int powerset = 800; //set power using this value int main(void) { //ADC Init_ADC(); //setup PWM: we're running at 9.6MHz, so 5-bit will give us 300 kHz, 6-bit 150 kHz. TCCR0A = 0b00100011; //set OC0B at TOP, clear on match, fast PWM with TOP=OCRA OCR0A = 64; //6-bit; TCCR0B = 0b00001001; //clkio/1 OCR0B = 0; //initialize at 0 duty cycle DDRB = 1 << 1; while(1) { curval = ADC_read(3); voltval = ADC_read(2) / 10; power = curval * voltval; if(power > powerset && OCR0B > 0) OCR0B--; if(power < powerset && OCR0B < 64) OCR0B++; } } |
[knip]
[ Voor 42% gewijzigd door mux op 19-11-2009 15:58 ]