Forum: Mikrocontroller und Digitale Elektronik Welche Auflösung / Frequenz für PWM?


von Lukas (Gast)


Lesenswert?

Hallo,

ich versuche mich gerade an einer Software-PWM. Evtl wirds auch ne BCm, 
das muss ich dann entscheiden wenn ich damit mehr Erfahrung hab :-)
Es sollen damit mehrere LEDs gedimmt werden. Später sollen dann 
mindestens 2 RGB LEDs angesteuert werden.

Bevor ich anfange stellt sich mir die Frage, welche Frequenz ich 
anstreben sollte, um kein Flackern zu haben bzw. schöne Farben zaubern 
zu können.

Ich hätte gerne 10 Bit Auflösung, um dann über eine hinterlegte 
logarithmische Tabelle das Ganze auf 8 Bit zu mappen.
Auserdem dachte ich erst an sportliche 200 Hz.
Laufen wird der Prozessor (ATmega32) später mit 8MHz.

Limitierend wirkt ja die Länge der ISR.
Deswegen werde ich 200Hz/10Bit wohl nicht schaffen, denn:
8000000 / (200*1024) = 39,0625.
So kurz werd ich die ISR nicht kriegen.

120 Hz würd ich momentan schaffen, da hätte meine ISR 65 Takte Zeit.
Hab nur Bedenken ob man da Flackern sieht. (Es soll ein Objekt 
illuminiert werden was fest im Raum steht, d.h. die Personen die das 
Objekt sehen sind in Bewegung, mit mehreren Metern Abstand).


Jetz überleg ich, soll ich mit der Auflösung runtergehen oder mit der 
Frequenz?
Was meint ihr?

von Falk B. (falk)


Lesenswert?

@ Lukas (Gast)

>ich versuche mich gerade an einer Software-PWM. Evtl wirds auch ne BCm,

Siehe Soft-PWM. Die hab ich letztes Jahr mit 20 MHz auf 24 Kanäle 
und 10 Bit ausgereizt.

Beitrag "Re: DMX Steuerung 24 Kanal"

>anstreben sollte, um kein Flackern zu haben bzw. schöne Farben zaubern
>zu können.

100 Hz sollten es schon sein und sind bei nicht bewegten LEDs meistens 
ausreichend.

von Lukas (Gast)


Lesenswert?

Den Artikel kenne ich.

Dort heißt es 10 Bit ermöglichen ein schönes weiche Fading. Deswegen 
strebe ich diese auch an.

Allerdings:
>> relativ niedrigen PWM Frequenz von 100 Hz

Deswegen hatte ich bedenken wegen der Frequenz...

Ok, aber deine 24-Kanal PWM arbeitet auch mit 100 Hz. Dann glaub ich dir 
mal dass des reicht.

von Roland L. (Gast)


Lesenswert?

wie schnell willst du die Helligkeit verändern?
bei 10bit Auflösung und  100Hz brauchst du 10s um den ganzen 
Helligkeitsbereich zu durchfahren.
Wenn du die Helligkeit schneller änderst, musst du ein paar 
Helligkeitsstufen überspringen, dann nützt dir die hohe Auflösung 
nichts.
Dann wäre eine höhere Frequenz sinnvoller.
Welche Frequenz ausreichend ist, wird auch von verschiedenen Menschen 
unterschiedlich empfunden.

von Lukas (Gast)


Lesenswert?

Hallo Roland,

wie kommst du auf die 10s? Meine Vermutung 10Bit ~ 1000 Werte, 1000 * 
1/100Hz = 10s. Richtig? Dann hätte ich jeden Wert einmal angefahren.

Nun, in meinem Projekt muss ich eher weniger die Farben wechseln. Meist 
soll das Objekt einfach nur bunt leuchten. Evtl. bau ich aber ein paar 
Wechsel als Gimmick ein. Aber das ist eben nicht primäres Ziel.

Sind dann also 10Bit @ 100Hz schon zuviel? Gäb ja auch noch die Option 9 
Bit (wobei ich nicht glaube dass das 9. Bit den Aufwand rechtfertigt, 
mit uint16_t Variablen arbeiten zu müssen. Soviele neue Werte mit 
logarithmischen Verhältnis sind dadurch ja nicht gewonnen...)

von Falk B. (falk)


Lesenswert?

@ Lukas (Gast)

>wie kommst du auf die 10s? Meine Vermutung 10Bit ~ 1000 Werte, 1000 *
>1/100Hz = 10s. Richtig? Dann hätte ich jeden Wert einmal angefahren.

Wenn man eine nichtlineare Kennline nutzt, sind es deutlich weniger 
Stufen. Eher so 128-256.

>Sind dann also 10Bit @ 100Hz schon zuviel?

Nein, passt schon.

von Lukas (Gast)


Lesenswert?

Ok, dann werd ich des ganze mal angehen: 10Bit bei 100Hz, ATmega läuft 
mit 8MHz.
Macht 78 Takte für die ISR, richtig?

Schau mer mal :-)

Was bisl doof ist: an dem Port sind bereits 2 Pins als GPIO vorgesehen. 
D.h. ich kann nicht einfach meinen Wert auf den Port schreiben sondern 
muss erstmal den Port einlesen, Maske setzen, mit dem neuen Wert 
verodern und dann kann ich erst schreiben...

Geht das irgendwie möglichst resourcen(=takt)schonend?

von Lukas (Gast)


Lesenswert?

So, ich nochmal...

Ich hab meine ISR jetzt soweit fertig.
Diese soll mir pro Aufruf einen vorher berechneten Wert auf einen Port 
ausgeben. Wie in meinem vorherigen Post beschrieben wird aber zuerst 
dieser Port eingelesen und maskiert, da auch "normale" Ausgänge an 
diesem Port hängen.
Anschließend wird das Timerregister aktualisiert.
1
     efc:  1f 92         push  r1
2
     efe:  0f 92         push  r0
3
     f00:  0f b6         in  r0, 0x3f  ; 63
4
     f02:  0f 92         push  r0
5
     f04:  11 24         eor  r1, r1
6
     f06:  0b b6         in  r0, 0x3b  ; 59
7
     f08:  0f 92         push  r0
8
     f0a:  2f 93         push  r18
9
     f0c:  8f 93         push  r24
10
     f0e:  9f 93         push  r25
11
     f10:  ef 93         push  r30
12
     f12:  ff 93         push  r31
13
     f14:  8b b1         in  r24, 0x0b  ; 11
14
     f16:  83 70         andi  r24, 0x03  ; 3
15
     f18:  90 91 65 04   lds  r25, 0x0465
16
     f1c:  e9 2f         mov  r30, r25
17
     f1e:  f0 e0         ldi  r31, 0x00  ; 0
18
     f20:  e3 5b         subi  r30, 0xB3  ; 179
19
     f22:  fb 4f         sbci  r31, 0xFB  ; 251
20
     f24:  20 81         ld  r18, Z
21
     f26:  82 23         and  r24, r18
22
     f28:  8b b9         out  0x0b, r24  ; 11
23
     f2a:  10 92 b2 00   sts  0x00B2, r1
24
     f2e:  8b b1         in  r24, 0x0b  ; 11
25
     f30:  88 0f         add  r24, r24
26
     f32:  8b b9         out  0x0b, r24  ; 11
27
     f34:  89 2f         mov  r24, r25
28
     f36:  8f 5f         subi  r24, 0xFF  ; 255
29
     f38:  8a 30         cpi  r24, 0x0A  ; 10
30
     f3a:  18 f4         brcc  .+6        ; 0xf42 <__vector_9+0x46>
31
     f3c:  80 93 65 04   sts  0x0465, r24
32
     f40:  04 c0         rjmp  .+8        ; 0xf4a <__vector_9+0x4e>
33
     f42:  10 92 65 04   sts  0x0465, r1
34
     f46:  83 ec         ldi  r24, 0xC3  ; 195
35
     f48:  8b b9         out  0x0b, r24  ; 11
36
     f4a:  ff 91         pop  r31
37
     f4c:  ef 91         pop  r30
38
     f4e:  9f 91         pop  r25
39
     f50:  8f 91         pop  r24
40
     f52:  2f 91         pop  r18
41
     f54:  0f 90         pop  r0
42
     f56:  0b be         out  0x3b, r0  ; 59
43
     f58:  0f 90         pop  r0
44
     f5a:  0f be         out  0x3f, r0  ; 63
45
     f5c:  0f 90         pop  r0
46
     f5e:  1f 90         pop  r1
47
     f60:  18 95         reti

Ich bin nicht so der Assemblerexperte. Kann mir bitte noch jemand mit 
drüber schauen?
Ich komme auf 74 Takte. Ist zwar knapp, sollte aber passen.
Habe 78 Takte zur Verfügung. Auser ich beachte grad irgendwas nicht, zB 
Delays beim Einsprung in die ISR.

Kann mir bitte jemand da drüber schauen?

von Falk B. (falk)


Lesenswert?

Mach ne Simulation im Simulator, der zählt dir die Takte.

von Ulrich (Gast)


Lesenswert?

Timer Register aktualisieren klingt irgendwie mach normalem Timer mode. 
Der Mega32 sollte genügend timer mit CTC mode haben - das spart schon 
mal die Manipulation am Timer. Das ist bei kleinem Vorteiler ohnehin 
problematisch.
Ein paar PWM Kanäle kann der µC auch in Hardware. Wenn die Auflösung mit 
8 Bit nicht reicht, kann man ggf. hier den 8 Bit Wert in Software 
Modulieren. Das ist immer noch schneller als echtes Software PWM.

Wie sieht denn der C Code aus.

Wenn man sich in ASM Anstrengt, kann man noch einiges mehr an 
Geschwindigkeit raus holen. Irgendwo bei 15 Zyklen plus 5 oder 6 je LED 
sollte das Limit liegen. Bei nur 6 Kanälen ggf. auch darunter.

Ein kleiner Trick, der auch in C noch gehen sollte, wäre es das unterste 
Bit getrennt zu bearbeiten, und Anfangs ein Zeitfenster mit halber 
Breite zu nutzen - das gibt mit relativ wenig zusätzlicher Laufzeit 1 
Bit mehr an Auflösung.

von DC (Gast)


Lesenswert?

Lukas schrieb:
> Ich hätte gerne 10 Bit Auflösung, um dann über eine hinterlegte
> logarithmische Tabelle das Ganze auf 8 Bit zu mappen.

Was meinst du damit?

von Falk B. (falk)


Lesenswert?


von Lukas (Gast)


Lesenswert?

DC schrieb:
> Lukas schrieb:
>> Ich hätte gerne 10 Bit Auflösung, um dann über eine hinterlegte
>> logarithmische Tabelle das Ganze auf 8 Bit zu mappen.
>
> Was meinst du damit?

Kurz: Von meinen 1024 möglichen Werten pick ich mir 256 raus die 
ungefähr im logarithmischen Verhältnis zueinander stehen (wobei 1024 
Werte da eigentlich nicht reichen).
Dadurch kann die nicht-lineare Helligkeitswahrnehmung des Auges 
ausgeglichen werden.

@ Falk: welchen Simulator? Imho gibt es momentan nur den von Atmel.
Das riecht dann nach Windows-VM mit Atmel-Studio aufsetzen :/

Oder gibts da Alternativen?

von Falk B. (falk)


Lesenswert?

@ Lukas (Gast)

>@ Falk: welchen Simulator?

AVR Studio.

> Imho gibt es momentan nur den von Atmel.
>Das riecht dann nach Windows-VM mit Atmel-Studio aufsetzen :/

Na dann mal los, Herr Pinguin ;-)

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.