[opnieuw] LED-driver met attiny13

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • mux
  • Registratie: Januari 2007
  • Laatst online: 03-09 11:04

mux

99% efficient!

Topicstarter
Na het vorige fiasco waar ik met een of ander vreemd hersenspinsel nieuwe natuurwetten uitvond, was ik nergens gekomen met mijn LED-driver, terwijl er wel LEDs liggen te verpieteren die op een fiets gebouwd moeten worden en fatsoenlijk gedimd moeten kunnen worden. Efficientie en constante lichtsterkte is belangrijk hier, want het geheel draait op een accu en LEDs hebben de neiging snel minder licht te geven bij een iets inzakkende spanning. Vandaar een buckconverter

Hiervoor gebruik ik dus een buck-converter met stroomsturing die je zelf kunt bouwen wanneer het eens nodig is om een vreemde LED aan te sturen.

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

en wat code (rudimentair)

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
54
55
56
57
58
59
60
61
62
63
#include <avr/io.h>
#include <stdio.h>

#define PWMD    128

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[5];
int curvall;
int voltval;
int power;

int curset = 105; //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 = PWMD; //6-bit;
    TCCR0B = 0b00001001; //clkio/1
    OCR0B = 0; //initialize at 0 duty cycle
    DDRB = 1 << 1;

    while(1)
    {
        curval[0] = ADC_read(1);
        curval[1] = ADC_read(1);
        curval[2] = ADC_read(1);
        curval[3] = ADC_read(1);
        curval[4] = ADC_read(1);

        curvall = curval[0] + curval[1] + curval[2] + curval[3] + curval[4];
        curvall /= 5;

        if(curvall > curset && OCR0B > 1) OCR0B--;
        if(curvall < curset && OCR0B < PWMD - 1) OCR0B++;

    }
}


Een saaie buckconverter met componenten die je op een willekeurig moederbord kunt vinden. De inductor is vandaag een 68uH 1.3A exemplaar en ik draai hem op 75 kHz, de tiny13 kan prima 300 kHz PWMen met 32-staps resolutie.

Voor maximale efficientie wil je mosfets van een willekeurig moederbord gebruiken (die zijn lekker snel en hebben een lage aan-weerstand, dus zowel schakel- als stroomverliezen worden geminimaliseerd). Een inductor van een moederbord plukken kan, maar dan moet je wel op 300 of 600 kHz werken en je tiny13 flink ontkoppelen. In de praktijk zijn de verliezen te hoog bij deze toepassing om dit te proberen, en zijn inductortjes met een hoge inductiewaarde klein genoeg.

Er doet zich echter een vervelend fenomeen voor, waarbij ik me afvraag hoe ik dit het beste kan oplossen. Dat is dit:

Afbeeldingslocatie: http://tweakers.net/ext/f/giiunsWVc7k0FHldEmhR0Az4/full.jpg

Dit is de spanning die over de meetweerstand valt. Wat je ziet zijn een hele hoop curves - bij een constante duty cycle hoor je maar één zaagtand te zien, hier zijn het er een stuk of 10. Bij een ongefilterde meetingang is dit niet vreemd, maar ik heb een gigantisch gefilterde meetingang (bandbreedte van ~100 Hz), dus ik zou dit helemaal niet moeten zien. Bovendien helpt running-average-meting niet (zie code), er blijft een hoop gewiebel op de meetingang. Zelf vermoed ik dat de ADC een sample-and-hold heeft met een wel heel grote sample-condensator waardoor mijn 100k-adc-weerstand te weinig stroom kan leveren maar... wat denken jullie? Niet dat dit een probleem is ofzo, de stroom wordt heel netjes geregeld binnen een paar procent, maar het zou leuk zijn om dit ding echt heel clean te krijgen.

Youtube: PowerElectronicsBlog - Plank2 (4W computer)


Acties:
  • 0 Henk 'm!

  • dbeijer85
  • Registratie: Januari 2007
  • Laatst online: 18-06 16:22

dbeijer85

Super fast charger

Als je denkt dat je ADC het probleem veroorzaakt, kan het dan niet helpen om een klein zuinig Opampje er tussen te zetten als buffer?

Assumption is the mother of all fuck-ups.


Acties:
  • 0 Henk 'm!

  • mux
  • Registratie: Januari 2007
  • Laatst online: 03-09 11:04

mux

99% efficient!

Topicstarter
Hm, ja, daar heb ik inmiddels niet zoveel ruimte meer voor. Echter, ondertussen heb ik een paar dingen geprobeerd:

- low-esr input&output caps voor de buckconverter: geen effect (maar wel stukken minder EMI)
- weerstand voor de adc van 100k naar 10k veranderd->enig effect.
- attiny beter ontkoppeld: geen effect (wel op

Er zit nog steeds een oscillatie in de aansturing, het lijkt in de honderden Hz te zitten. Hij lijkt mooi sinusoidaal te zijn dus ik denk dat ik maar softwarematig een bandstop filter erin bouw.

Youtube: PowerElectronicsBlog - Plank2 (4W computer)


Acties:
  • 0 Henk 'm!

  • mux
  • Registratie: Januari 2007
  • Laatst online: 03-09 11:04

mux

99% efficient!

Topicstarter
Goed, het volgende punt dient zich aan: communicatie. De bedoeling is dat mijn lichten met mijn fietscomputer (een atmega162) gaan communiceren. De lichten meten stroom en spanning (niet in het schema getekend) met PB4 en gebruiken PB0 en PB3 als communicatie-pinnen. Mijn bedoeling was om een clock+data-protocol te maken waarin de PCINT interrupt wordt gebruikt op één van de pinnen als dataklok, in de interrupt de 'volgende bit' wordt klaargezet danwel ingelezen. Over dit protocol wordt verstuurd:

- licht aan/uit (162->13)
- intensiteit (162->13)
- spanning (13->162)
- stroom door lamp (13->162)

In principe kan de 162 altijd kloks sturen naar de tiny13, waarna alle informatie volgens een vast patroon heen en weer wordt gestuurd. Het probleem waar ik tegenaan loop is dat ik eigenlijk niet weet hoe ik fatsoenlijk en niet al te software-intensief message alignment kan doen. De tiny13 krijgt kloks, maar hij kan een of twee kloks gemist hebben (langere init-tijd, wat dan ook). Hij moet dus wel weten wanneer welke bit aan de beurt is. Eerder heb ik al eens morsecode tussen een tiny13 en mega162 gemaakt, (echte 1-wire dus), daar was helemaal geen kloklijn dus moest ik wel alignen. Dit gebeurde door de morsecode in een char array te stoppen, na 8 transfers te kijken of de eerste vier bits '1010' waren en zoniet, de index 1 op te schuiven en nog eens te proberen. Maar dat lijkt me niet echt de mooiste methode, is er iets beters?

Youtube: PowerElectronicsBlog - Plank2 (4W computer)


Acties:
  • 0 Henk 'm!

  • Looney11
  • Registratie: December 2004
  • Laatst online: 13-09 14:29
Is die hoeveelheid zaagtanden wellicht het resultaat van oscillatie aan de uitgang? Een zaagtand brengt zowieso een hoop troep met zich mee. wellicht een filtertje gebruiken of kijken of de atiny zelf loopt te oscilleren..

Acties:
  • 0 Henk 'm!

  • mux
  • Registratie: Januari 2007
  • Laatst online: 03-09 11:04

mux

99% efficient!

Topicstarter
Die hoeveelheid zaagtanden is vast en zeker resultaat van oscillatie aan de uitgang, want het is de spanning over de meetweerstand, die in serie met de belasting staat. Elke zaagtand is een andere PWM duty cycle. Het probleem is echter wel minder erg dan het leek: als ik er een LED aan hang (ipv hier: een vermogensweerstand) jittert hij nog maar tussen 3 standen, wat prima acceptabel is. Ik laat het voorlopig maar even voor wat het is, nog genoeg andere dingen op te lossen.

Youtube: PowerElectronicsBlog - Plank2 (4W computer)

Pagina: 1