Highpower LED-driver met Attiny13

Pagina: 1
Acties:

  • mux
  • Registratie: Januari 2007
  • Laatst online: 11-10 19:46

mux

99% efficient!

Topicstarter
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:

Afbeeldingslocatie: http://tweakers.net/ext/f/1ZIDSIrJqYwOUmXnhSW4AexF/full.png

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 ]


  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 12-10 06:44

Sprite_tm

Semi-Chinees

Paar dingetjes:

Ten eerste: je zou softwarematig een overbelasting tegen kunnen gaan: als je merkt dat je duty-cycle erg hoog is terwijl je 0 stroom meet, kan je in een fout-toestand schieten waarbij je alles uitzet. Je led overleeft 't wel als je het snel genoeg doet.

Ten tweede: meerdere leds, zonder voorschakelweerstand, parallel? Dat gaat nooit goed; ook hier is het weer zo dat als de drempelspanning van 1 van de LEDs net iets lager is dan de rest, dat daar alle stroom doorheengaat. Die word dan overbelast en kan stuk gaan (waardoor btw de rest ook overbelast word.) Je kan beter je leds in serie schakelen; als je voedingsspanning dat niet toelaat is het vrij simpel om het schakelingetje om te zetten in een boost-converter zodat je voedingsspanning minder mag wezen (veel minder zelfs) dan de opgetelde drempelspanningen van de leds.

(Je krijgt met een boostconverter dan wel weer andere leuke situaties: ik heb met een ontkoppelde belasting wel es gehad dat een ATTiny op 3V een elko rated op 25V opblies... een algorithmische of electrische beveiliging is daar dus nog wat meer aan te raden.)

En ten derde: mocht je dit willen implementeren kan ik je aanraden om naar de interrupt-mogelijkheid van de AVR te kijken. Als je daarmee je code goed schrijft, kan je namelijk je main-programma schrijven zonder dat je continue bewust je led-stroom moet bijregelen. Works like a charm.

* Sprite_tm wijst ook nog even naar z'n huidige sig, staat ook het eea in over led-dimming.

[ Voor 28% gewijzigd door Sprite_tm op 19-11-2009 13:20 ]

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • Cassettebandje
  • Registratie: Juli 2002
  • Laatst online: 16:53

Cassettebandje

SA-C90 TDK

Als je nog meer andere dingen wilt doen met je mcu kun je het ad-converteren en het berekenen evt in interrupts doen, een timer interrupt en een voor de ad conversie.
De code zou eventueel ook nog sneller kunnen door in regel 47 te delen door 8 met een shift in plaats van een division operatie (== langzaam). De waarde voor powerset komt dan 25% hoger uit, maar die kun je toch zelf instellen. Bijkomend voordeel is dat de lengte van je while lus qua tijd waarschijnlijk (bijna) constant wordt (tijdsduur van een deling hangt, in tegenstelling tot de andere operaties, meestal af van de gegeven waarden).
'K vind het een leuke schakeling :)

  • mux
  • Registratie: Januari 2007
  • Laatst online: 11-10 19:46

mux

99% efficient!

Topicstarter
Die meerdere LEDs parallel is wel een leuke: Ik stuur hier dus een 4W LED mee aan die in feite uit 4 1W LEDs bestaat. Blijkbaar zijn ze gematcht ofzo, want als ik dit met een zakje blauwe LEDs probeer krijg ik de helft die veel zachter brandt dan de rest. Anyway, je hebt helemaal gelijk, de LEDs staan hier maar voor de sier in parallel, houd daar rekening mee als iemand anders deze schakeling wil namaken.

En @Springuin: jep, het is maar voorbeeldcode. Ik moet nog uitvinden hoe groot ik m'n statements mag maken zonder de stack te overbelasten, maar dat was ik ook nog van plan te reduceren. En ohja, er komen nog seriele communicaties tussen mn lampen en fietscomputer, maar dat is een heel ander vlak.

  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 12-10 06:44

Sprite_tm

Semi-Chinees

Ow, nog een dingetje: waarom loop je de PWM-waarde bij te regelen op het vermogens-verbruik van de hele buck-converter? In principe mag je ervanuit gaan dat LEDs her prima doen als je er X mA doorheengooit (met de X uit de datasheet van de led gehaald): de drempelspanning van de LEDs zorgt daar namelijk voor. Ik zou dus zeggen: gooi die voedingsspanningmeting eruit en gat het zooitje bijregelen op de stroom die je dmv de shunt meet. Scheelt je meteen weer een AD-conversie, waardoor je schakelingetje nog eens 2x zo snel kan bijregelen.

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • mux
  • Registratie: Januari 2007
  • Laatst online: 11-10 19:46

mux

99% efficient!

Topicstarter
Maar zo werkt het niet. Je meet de stroom die door de hele serie heen gaat, en die is totaal niet gelijk aan de belastingsstroom. Met deze schakeling weet je niet hoeveel stroom er door je LEDs gaat.

Als ik de stroom zou regelen op 350 mA (mijn achterlicht) of 700mA (voorlicht), dan zou hij van 1 tot 15V er 350mA doorheen rammen. Dat is niet bepaald de bedoeling.

Het hele idee is ook dat LEDs totaal nonlineair zijn (theoretisch exponentieel, maar ze warmen flink op dus ze zijn meer dan exponentieel gezien diodes een lagere Vf hebben bij hogere temperatuur), en je dus niks hebt aan lineaire regeling (spanningsconverter). Vandaar het LC-filter met totale vermogensregeling. Bovendien kan ik op deze manier op mijn stuur zien hoeveel er wordt verbruikt door al mijn apparatuur, ram ik een coulomb counter op mijn accu en weet ik de levensduur van de accu en kan zodanig op de minuut precies zeggen hoe lang ik nog op een accu kan werken.

  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 12-10 06:44

Sprite_tm

Semi-Chinees

Wacht eens even; hoe langer ik naar je schakeling kijk, hoe vreemder mij 'm voorkomt. Je gebruikt hier een aantal componenten die ook in een buck-converter voorkomen, maar volgens mij gebruik je hier eigenlijk gewoon PWM over een condo, en werkt de spoel hier als een veredelde weerstand :?

Uitleg: Een buck-converter werkt, simpel gesteld, doordat je twee stroomkringen afwisselt. Je laat de spoel in de eerste instantie een magnetisch veld opbouwen door 'm in serie met de belasting en de spanningsbron te zetten. De tweede stroomkring haalt de spanningsbron uit het plaatje en de spoel voedt zelf door z'n inklappende magnetisch veld de belasting.

Het eerste lijkt bij jou wel aanwezig te zijn: als je de mosfet aanzet staat de spoel in serie met de belasting en de batterij. Als je mosfet uitgaat heb je echter een probleem: het magnetisch veld van de spoel klapt in en de spoel wil daardoor een stroom laten lopen. Dat kan echter niet meer: er is geen pad tussen beide aansluitingen van de spoel aanwezig. Theoretisch gezien gaat dan de spanning oplopen tot je mosfet boem zegt. Practisch gezien zijn je copmponbenten (blijkbaar) niet ideaal en overleeft alles het.

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • mux
  • Registratie: Januari 2007
  • Laatst online: 11-10 19:46

mux

99% efficient!

Topicstarter
Ha, hij heeft hem door. Dit is geen buck converter! Het is een zwevend LC-filter!

Dit werkt puur en alleen doordat de belasting een diode is en de inductor een kleine waarde heeft. Als je dit met een 1mH inductor met meer dan een paar mohm weerstand zou doen zou je spanning keihard oplopen en alles kapoet maken. Leuk hè, experimenten van dit soort. Vandaar ook mijn verbazing dat dit zo goed werkt. Het bijkomend voordeel is dat dit circuit makkelijk te meten en aan te sturen is (in tegenstelling tot een buckconverter, die een high-side switch heeft) en nog steeds (door de kleine duty cycle) vrijwel verliesloos is.

Als je het geheel met ESRs gaat uittekenen zie je dat het wel werkt. Kritisch is dat je een toroide inductor van een moederbord neemt, met weinig hele dikke windingen.

Afbeeldingslocatie: http://tweakers.net/ext/f/WxlfArk8KKlo1FDRfbPAKnXZ/full.png

Misschien moet ik de disclaimer nog maar wat duidelijker maken: als je hier je scope niet aan hangt, is dit een redelijk gevaarlijk circuit!

Anyway, wanneer ik een vrijloopdiode erop zet is er zo goed als nul verschil met puur de EPR van de L het werk laten doen. Leuk hè?

[ Voor 18% gewijzigd door mux op 19-11-2009 15:41 ]


  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 12-10 06:44

Sprite_tm

Semi-Chinees

Hoooookeeeeej.... maar wat is dan de reden dat je je spoel niet gewoon vervangt door een weerstand? Effectief zit daar geen verschil tussen voor zover ik 't zo kan inschatten; je gebruikt je spoel hier gewoon als stroom-beperkend iets terwijl je de energie die 'ie daardoor opzuipt in je uit-cyclus opstookt in je parasitaire weerstand van de spoel.

Edit: Hmmm, ik zoek net even naar de term 'zwevend lc-filter' om te kijken of dat misschien een apart concept is wat ik nog niet ken. Enige hit: Dit topic. Damn, Google is rap!

[ Voor 54% gewijzigd door Sprite_tm op 19-11-2009 15:43 ]

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • mux
  • Registratie: Januari 2007
  • Laatst online: 11-10 19:46

mux

99% efficient!

Topicstarter
Nee, als je er een weerstand voor gebruikt heb je een dissipatief circuit: de belastingsstroom is dan de voedingsstroom, en je bent net als in een LDO gewoon alle spanning die teveel is aan het wegbranden. In dit circuit wordt de uitgangselco door een inductor geladen wat (theoretisch) verliesloos is. In de praktijk is dit ook zo goed als verliesloos, mijn 1W led loopt op, wat mijn voeding aangeeft, zo goed als precies 1W.

  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 12-10 06:44

Sprite_tm

Semi-Chinees

Mijn punt is dat een buck-converter e.d. alleen verliesloos is omdat de energie die de spoel opsoept zodra de voeding eraanhangt, opgeslagen word als een magnetisch veld inplaats te dissiperen als warmte. Dat magnetische veld kan daarna weer even hard gebruikt worden om de belasting te voeden als de voeding losgekoppeld is, en daardoor is het juist zo efficient. In jouw geval ontlaad je de energie die je in je spoel opslaat echter later alsnog over een weerstand, waardoor het alsnog omgezet word in warmte en je efficientie dus weer even groot is als een resistieve oplossing.

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • mux
  • Registratie: Januari 2007
  • Laatst online: 11-10 19:46

mux

99% efficient!

Topicstarter
Hm, bij nader inzien is dit toch analytisch een denkfout... Ik raak wel best veel van mn energie kwijt. Toch maar een buckconverter bouwen?

Ik dacht een verklaring te hebben waarom het werkte, maar die loopt spaak. Echter, het werkt wel, want als ik evenveel stroom door mn ledjes heengooi als door deze schakeling bij hoge spanning, dan branden ze minder fel (dus, ergens wordt energie met minder verlies opgeslagen dan anders). Hmmm...

[ Voor 51% gewijzigd door mux op 19-11-2009 15:57 ]


  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 12-10 06:44

Sprite_tm

Semi-Chinees

Kan de beste gebeuren; tis niet altijd makkelijke materie ;) En jah, dan lijkt een buck-converter me een beter idee.

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • mux
  • Registratie: Januari 2007
  • Laatst online: 11-10 19:46

mux

99% efficient!

Topicstarter
Het brakke is dat ik dit soort dingen moet weten, ik studeer er op af, maar ik heb het blijkbaar niet netjes genoeg uitgetekend voor ik het ging bouwen. Anyway, de verbeterde versie komt wel in dit topic te staan, ik heb namelijk nog een mooie bootstrapping driver liggen :D
Pagina: 1