Forum: Mikrocontroller und Digitale Elektronik Soft PWM noch zu schnell


von Danny (Gast)


Lesenswert?

Hallo zusammen...

Ich habe folgndes Problem: Ich habe das Tutorial durchgearbeitet und mir 
testweise die intelligente LSG des soft PWM kopiert - das problem ist 
jetzt nur, dass selbst wenn ich die 1 als Helligkeit in dem Array 
eingebe ist die LED noch immer viel zu hell um sie langsam ausfaden zu 
lassen... ich habe das erstmal mit einer einzelnen probiert - wie gesagt 
zum Test - sinn der Sache ist es nachher eine RGB LED anzusteuern - nur 
wenn die einzelne LED nicht fast vollständig aus geht, sind die 
einzelnen Farbanteile der RGB auch zuu hell... versteht ihr was ich 
meine... ?!

Ich suche eine Möglichkeit den Code so anzupassen, dass die einzelne LED 
fast vollständig aus geht! Ich meine dass das am dem Timer liegt - der 
müsste schneller zählen, dass das ausschalten-Interrupt schneller 
gesetzt werden kann, aber wie und vor allem wo mach ich das in dem Code 
aus dem Tut? 
(http://www.mikrocontroller.net/articles/Soft-PWM#Intelligenter_L.C3.B6sungsansatz)
Mit dem normalen PWM aus dem "Thema" LED-Fading geht das ja auch 
wunderbar, nur ist das eben nur für eine begrenzte Anzahl von Pins...

Über Lösungsansätze oder Gendanken wäre ich mehr als Dankbar... :)

MfG Danny

von Danny (Gast)


Angehängte Dateien:

Lesenswert?

Kann mir bite jemand helfen ?? Ich habe im Forum schon einen 
Lösungsansatz erhalten, wie ich das alles auf einen 16 Bit timer 
umschreiben kann, aber da sind ne Menge Wert zu beachten...

Hier im Anhang ist, was ich bisher habe - könnt ihr das mal überprüfen 
und evtl korrigieren ?? Ich wäre euch sehr verbunden :) ich habe schon 
alles durchgesehen, aber finde des Rätsels Lösung immer noch nicht... =(

Danke schonmal vorab...

von TokyoDrift (Gast)


Lesenswert?

du hast nur 2 möglichkeiten das dunkler zu bekommen, entweder du machst 
die LED grundsätzlich dunkler (=> widerstand) oder du verringerst das 
tastverhältnis
und da es mit 8 bit timern eben nich kleiner als 1/256 geht musst du 
eben 16 bit timer nehmen um dann als kleinsten wert 1/65536 zu haben

von Danny (Gast)


Lesenswert?

genau - das hattest du mir ja im Forum schon gesagt - danke nochmal - 
ich habe auch soweit versucht alles auf 16-Bit timer umzuschreiben, aber 
ich dneke ich habe nicht ganz alles bedacht... ?! ich habe in dem 2. 
Post den überarbeiteten Code... ich bräuchte noch ein Paar Fehler, die 
sich dort versteckt haben... selbst mit einem prescaler von 1 flackert 
die LED recht langsam... war darauf schließen lässt, dass die Frequenz 
des PWM zu klein ist, aber da entstehen wieder andere Fehlerquellen in 
diesem code.... ich habe oben wie gesagt das überarbeitete - wenn ihr da 
mal einen Blick drauf werfen könntet wäre ich euch treu ergeben ;)

Danke!

von Hans_Dampf (Gast)


Lesenswert?

1
ISR(TIMER1_COMPA_vect)
2
{
3
    static uint16_t pwm_cnt;
4
    uint16_t tmp;
5
 
6
    OCR1A += isr_ptr_time[pwm_cnt];
7
    tmp    = isr_ptr_mask[pwm_cnt];
8
    
9
    if (pwm_cnt == 0) {
10
        PWM_PORT = tmp;
11
        pwm_cnt++;
12
    }
13
    else
14
    {
15
        PWM_PORT &= tmp;
16
        if (pwm_cnt == pwm_cnt_max)
17
        {
18
            pwm_sync = 1; 
19
            pwm_cnt  = 0;
20
        }
21
        else pwm_cnt++;
22
    }
23
}
24
 
25
int main(void)
26
{
27
    PWM Port einstellen
28
    PWM_DDR = 0xFF;         // Port als Ausgang
29
    // Timer 1 OCRA1, als variablen Timer nutzen
30
    TCCR1B = 1;             // Timer läuft mit Prescaler 64
31
    TIMSK |= (1<<OCIE1A);   // Interrupt freischalten
32
    sei();   
33
               // Interrupts gloabl einschalten
34
    ...
35
 
36
// Debug 
37
 
38
    memcpy(pwm_setting, t1, 16);
39
    pwm_update();
40
41
42
/* 
43
  ...
44
*/
45
/******************************************************************/
46
 
47
    while(1);
48
    return 0;
49
}

Du hast aber schon gesehen, dass Deine "pwm_update();" Funktion genaut 
einmal aufgerufen wird und zwar bevor Dein Programm in die 
while(1)-Schleife springt?!

von Danny (Gast)


Lesenswert?

jo jo danke für den Timm bzgl. der while schleife - das ist nur zum 
test, die LEDs gehen denn 1x an und bleiben an - nur zum testen wie 
gesagt.... :)

Aber danke erstmal für deinen code - ich werde ihn gleich mal 
ausprobieren... =)

-> 10 min. später <-

hmm leider noch kein Erfolg - ich habe das gefühl es ist egal was ich 
ihm als input gebe (im tutorial die Beispielarrays - er schaltet immer 
bit 0,3 und 4 an - wobei bit 4 als 1. aus geht, dann 3 und dann bit 0 - 
egal was ich ihm eingebe - ich nehme an schon in den oberen schleifen 
wird etwas nicht stimmen bzw. i-was kommt damit nicht klar, dass der 
timer jetzt bis 65536 zählen kann.... :?

Hat niemand eine funktionierende Lösung für die 16 bit soft PWM ?
Ider lass und diese Version aus dem Tutorial stück für stück auf 16 bit 
umschreiben.... - so leicht geben wir uns doch nicht geschlagen oder was 
;)

von Falk B. (falk)


Lesenswert?

@  Danny (Gast)

>Hat niemand eine funktionierende Lösung für die 16 bit soft PWM ?

Die gibt es nicht. Das steht auch im Artikel Soft PWM.

Man könnte aber mit einem Trick arbeiten. Man verwendet zwei 
Vorwiderstände. Den normalen, der wird schaltbar gemacht. Und einen der 
1/256 des normalen ist, der ist fest. Mit dem kleinen Vorwiderstand kann 
man sehr fein auflösen, wenn man dann bei 255 angekommen ist, wird auf 
volle Leistung umgeschaltet. Fertig ist eine pseudo 16 Bit PWM.

MfG
Falk

von Hans_Dampf (Gast)


Lesenswert?

>Aber danke erstmal für deinen code - ich werde ihn gleich mal
>ausprobieren... =)

Ist nicht von mir, ist Deiner nur etwas umformatiert! Kleiner Tip, eine 
saubere Form deines Programms ist ein enormer Zugewinn, was die 
Lesbarkeit angeht! :-)

Hier meine Soft-PWM(8-Bit)
1
volatile unsigned char Counter, Merker_Timer0;
2
unsigned char PWM;
3
4
...
5
6
void Timer_init()
7
{
8
    TCCR0 |= (1<<CS00);   
9
    TIMSK |= (1<<TOIE0);  
10
}
11
12
...
13
14
ISR (TIMER0_OVF_vect)      // Timer0 Overflow 
15
{
16
  Counter++;      // Zeitbasis für Software PWM 
17
  
18
        if(Counter < PWM )    // SOFTWARE-PWM Modul
19
            LED=0;            // PWM Grundfrequnez ergibt sich zu
20
   else          // 16MHz / ( 256*256) = 244.1 Hz
21
            LED=1;
22
23
  Merker_Timer0=1;
24
}

(In meinem Programm setzt ein LED=0 bzw. =1 noch nicht direkt die LED, 
solltest Du ersetzen durch PORTX &= ~(1 << Y) für =0 und PORTX |= (1 << 
Y) für =1)

Was ist denn das für eine LED die Du da hast, dass die bei 1/256 ihres 
Nennstromes noch so hell ist?

Gruß

von Falk B. (falk)


Lesenswert?

@  Hans_Dampf (Gast)

>Was ist denn das für eine LED die Du da hast, dass die bei 1/256 ihres
>Nennstromes noch so hell ist?

Das muss keine besondere sein, siehe LED-Fading.

von Hans_Dampf (Gast)


Lesenswert?

>@  Hans_Dampf (Gast)

>>Was ist denn das für eine LED die Du da hast, dass die bei 1/256 ihres
>>Nennstromes noch so hell ist?

>Das muss keine besondere sein, siehe LED-Fading.

Die LEDs mit denen ich arbeite sind bei einem Tastverhältnis von 1:256 
fast nicht mehr wahrzunehmen.

Interessiert mich immernoch, was Du da für LEDs hast.

von Danny (Gast)


Lesenswert?

Hmm ich bin gerade nicht zu Hause, aber ich habe mir mal bei eBay solche 
superhellen LEDs gekauft - die haben 16000 mcd oder so - aber ich schaue 
nochmal nach !

bei den roten LEDs steht jedenfalls 1,8-2,2 V und 20-30 mA drauf und ich 
glaube 12.000 mcd...

ob das daran liegt dass die besonders hell sind ? Ich hatte damals 
darauf geachtet, dass ich die hellsten bekomme die ich bei ebay finden 
konnte... Vllt liegt es ja daran.... :?

Danke erstmal für eure Tipps =)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.