mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Led Fading mit Soft PWM "ruckelt"


Autor: RGB und AVR-Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend!

Ich beschäftige mich seit kurzer Zeit mit AVRs. Ich möchte auf lange 
Sicht gerne eine Farbmischung mittels einer RGB Led programmieren.

Nun habe ich erstmal angefangen einen Chip(also eine Farbe der LED) mit 
SoftPWM  heller und dunkler zu faden.
Leider flackert und ruckelt die Farbmischung sehr stark(vorallem in 
"dunkleren" Bereichen).

Hardware(hier sollte alles richtig sein):
Als Hardware habe ich einfach den entsprechenden Pin der LED mit 
Vorwiederstand an den Portpin des AVR angeschlossen.

Software/Pseudocode(ist hier ein Denkfehler?):

Taktfrequenz vom Atmega ist 1MHz
Ich betreibe den Timer im normalen Modus mit Prescaler 1.
Der Timer löst einen Overflow Interrupt aus.

In der Interruptroutine wird eine Variable(z.B. "heller") hochgezählt 
solange sie kleiner als z.b. 255 ist.

Im Hauptprogramm wird nichts gemacht außer die Led anzuschalten wenn 
TCNT0(der aktuelle Timerwert) kleiner als "heller" und sie auszuschalten 
wenn TCNT0 größer als "heller" ist


Es wäre super, wenn mir jemand weiterhelfen kann.
P.S.: Mein Problem ist nicht, dass die LED sehr schnell hell wird und 
dann hell bleibt, was ja an der Kennlinie des menschlichen Auges liegt!

Nochmal genau wie sich die LED verhält:
- erst blitzt die LED immer nur kurz auf, flackert also langsam
- ab einer gewissen Helligkeit ist das Flackern weg und die LEd leuchtet 
relativ homogen, aber die Helligkeitssprünge sind abrupt/ sprunghaft und 
nicht flüssig

Vielen Dank für eure Hilfe

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, mal wieder keinen echten Code gepostet... Gibt ne 5 und ausserdem 
nur Vermutungen.

Ohne den AVR genau zu kennen und auch nicht zu wissen, ob der Timer 8- 
oder 16-Bit breit ist, würde ich mal vermuten, dass dein Ruckeln durch 
die zu langsame Taktfrequenz kommt...

Gehe ich von einem MHz Takt aus, braucht der Timer bei 16-Bit etwa 65ms, 
was wiederum 15Hz entspricht, und das würde ich als flackernde 
PWM-Frequenz ansehen.

Also, entweder Taktrate erhöhen, oder Timer bei 16-Bit nicht voll 
durchlaufen lassen oder für einen schnellen Test auf 8-Bit setzen.

Ralf

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RGB und AVR-Anfänger schrieb im Beitrag #1750283:

> Im Hauptprogramm wird nichts gemacht außer die Led anzuschalten wenn
> TCNT0(der aktuelle Timerwert) kleiner als "heller" und sie auszuschalten
> wenn TCNT0 größer als "heller" ist

Das ist unbrauchbar. Damit kriegst du keine stabile PWM mit immer 
konstanten Pulsbreiten hin. TCNT0 verändert sich viel schneller als das 
dein Programm das mitkriegen würde.

Zeig dein Programm und beschreibe es nicht.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und dreh als erstes die Taktfrequenz deines Mega hoch, wenn das möglich 
ist.

Autor: thisamplifierisloud (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: RGB und AVR-Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke euch allen schonmal für die Hilfe.
Ihr habt Recht, mein Beitrag hätte wohl besser sein können.

Ich hab sehr viele Versuche gemacht - mit verschiedenem code.

Ein Beispiel in dem die Farbsprünge am Anfang gut zu sehen sind ist 
dieser code:

(Das verhalten der LED: dunkel...etwas heller --> Sprung: nen gutes 
Stück heller...etwas heller --> Sprung: nen gutes Stück heller - sobald 
die Led noch heller wird sind keine Sprünge mehr zu sehen)
#ifndef F_CPU
#define F_CPU 1000000UL 
#endif

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define rot_an    PORTA |= (1 << PA2)
#define rot_aus    PORTA &= ~(1 << PA2)

// Variablen definieren
volatile uint8_t rot;

// ***** Timer2-Overflow-Interrupt ******
ISR (TIMER2_OVF_vect){ 
// zähle die Variable rot von 0-254
rot++;
if (rot > 254) {timer = 0;}
}

// ***** Hauptprogramm *****
int main(void){
// Variablen setzen
rot = 0;

// PortA zu Ausgängen
DDRA= 0xff; 
PORTA= 0b00000000; 

// PB0 als Eingang, Pull-Up aktivieren
DDRB  &= ~(1<<PB2);  
PORTB |= (1<<PB2);     
                
// Timer 0 konfigurieren: Prescaler 1
TCCR0 = (1<<CS00);

// Timer 2 konfigurieren: Prescaler 1024
TCCR2 = (1<<CS20)|(1<<CS22);
// Overflow Interrupt Timer 2 aktivieren
TIMSK |= (1<<TOIE2);

// Global Interrupts aktivieren
sei();

// ***** Endlosschleife *****
while(1){

if (TCNT0 < rot) {rot_an;}
else {rot_aus;}


} //eof while

} //eof main


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RGB und AVR-Anfänger schrieb im Beitrag #1750377:

Wie schon gesagt, ist das

> // ***** Endlosschleife *****
> while(1){
>
> if (TCNT0 < rot) {rot_an;}
> else {rot_aus;}


zwar nett gedacht, aber unbrauchbar.
Du erwischt mit dem Code nicht oder nur zufällig den Zeitpunkt an dem 
TCNT0 genau die Schwelle des Grenzwertes überschreitet. Wenn dann noch 
mehr Code dazu kommt, wirds noch zufälliger.

Du brauchst definierte Zeitpunkte.
Mit dem Overflow Interrupt des Timers 0 wirst du mehr Glück haben. Den 
PWM Zähler musst du dir selber aufbauen.
Mit lediglich 1Mhz Taktfrequenz wirds aber eng mit einer 8Bit PWM. Daher 
muss die Taktfrequenz rauf. Kann dein µC interne 8MHz?


Allerdings wirst du auch dann, bei den kleinen Helligkeitsstufen Sprünge 
sehen. Unsere Augen sind da einfach zu empfindlich.

Autor: RGB und AVR-Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, nun bin ich schon etwas schlauer.

Ich werde also den Overflow-Interrupt vom Timer nutzen um eine Variable 
hochzuzählen und zurückzusetzten (von z.b. 0-254) um dann diese mit 
meiner Variable "rot" zu vergleichen?
     - ist das so richtig ?

Beim CPU möchte ich später einmal einen Attiny25 nutzen(daher auch 
Software PWM).
Die Taktfrequenz hatte ich auf 1Mhz gelassen da ich gerechnet hatte 1Mhz 
/ 256 /1(Prescaler aus) = 3906,25Hz. Daraus geschlossen hatte ich 
geschlossen, dass die Frequenz locker ausreicht

Wie kann ich denn die Helligkeitssprünge weitestgehend vermeiden ?

Vielen Dank für eure Mühe.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  RGB und AVR-Anfänger (Gast)

>Wie kann ich denn die Helligkeitssprünge weitestgehend vermeiden ?

Durch Lesen und Anwenden des Artikels LED-Fading.

MFG
Falk

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RGB und AVR-Anfänger schrieb im Beitrag #1750415:
> Danke, nun bin ich schon etwas schlauer.
>
> Ich werde also den Overflow-Interrupt vom Timer nutzen um eine Variable
> hochzuzählen und zurückzusetzten (von z.b. 0-254) um dann diese mit
> meiner Variable "rot" zu vergleichen?
>      - ist das so richtig ?

genau.
Wenn du sie von 0-255 laufen lassen willst, dann mach sie als uint8_t 
Variable, dann brauchst du sie auch nicht zurücksetzen.

> geschlossen, dass die Frequenz locker ausreicht

jetzt dann nicht mehr
  1000000 / 256 / 256 = 15.irgendwas
das Flackern sieht man dann.

> Wie kann ich denn die Helligkeitssprünge weitestgehend vermeiden ?

Gar nicht. Dazu muss die Bitanzahl der PWM rauf. die hast du aber nicht.
Von einer PWMstufe von 0 auf 1 hast du nun mal einen Sprung. Von 1 auf 2 
hast du wieder einen Sprung.
genauso wie du von 234 auf 235 einen Sprung hast.
Nur sind unsere Augen bei kleinen Helligkeiten empfindlicher. Dort 
merken sie den Sprung, während bei den großen Helligkeiten der Sprung 
nicht weiter auffällt.
Tun kannst du dagegen nichts, ausser die PWM Bitanzahl hochzudrehen. 
Aber dann kommst du mit der Taktfrequenz nicht mehr hin, so dass nichts 
flackert.
Die sichtbaren Sprünge sind physikalisch bedingt. Und Physik lässt sich 
nun mal nicht überlisten.

Autor: RGB und AVR-Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vieln Dank an Alle und vorallem an dich Karl heinz Buchegger!

Nun habe ich die Problematik verstanden!

P.S. die Artikel Led-Fading(und einige andere) kannte ich schon, jedoch 
ist es manchmal schwer nur vom Lesen allein alles zu verstehen.

Schönen Abend noch!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RGB und AVR-Anfänger schrieb im Beitrag #1750435:
> P.S. die Artikel Led-Fading(und einige andere) kannte ich schon, jedoch
> ist es manchmal schwer nur vom Lesen allein alles zu verstehen.

Der Artikel LED-Fading ist dann nützlich wenn es darum geht mit einer 16 
Bit PWM einen konstanten Helligkeitsanstieg in einer bestimmten Zeit zu 
erreichen. Am grundsätzlichen Problem, dass bei kleinen PWM Bitzahlen in 
den kleinen Werten sichtbare Sprünge existieren, kabnn auch er nichts 
ändern.

Autor: Sepp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der ATTINY24 hat bereits einen richtigen 8Bit PWM eingebaut!

Grüße,
Sepp

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.