Hallo,
um 8 LEDs unabhängig voneinander langsam heller und wieder dunkler
werden zu lassen, habe ich versucht, das Beispielprogramm aus dem
Artikel Soft-PWM http://www.mikrocontroller.net/articles/Soft-PWM
(die 1. Variante) zu verstehen und zu modifizieren. Bisher habe ich es
immerhin geschafft, den PWM-Wert für Pin D0 in einer schleife hochlaufen
zu lassen. Aber jetzt ist meine große Frage:
Wie schaffe ich es, 8 Kanäle mit verschiedenen Geschwindigkeiten und
Startzeiten hoch-und runterlaufen zu lassen?
Geanau wie im Artikel verwende ich einen ATMEGA32 mit internen 8MHz.
Für hilfreiche Tipps oder Links, die anfängertauglich sind, bin ich sehr
dankbar!
Sascha
> ISR(TIMER1_COMPA_vect)> {> static uint8_t pwm_cnt=0;> uint8_t tmp=0, i=0, j=1;> //const uint8_t t1[8]={27, 40, 3, 17, 150, 99, 5, 9};> //pwm_setting[8]=t1[8];> pwm_setting[0]=PWM_ch1;
Ähm.
Was hat das da drinn verloren? Das gehört da nicht her.
Du scheinst nicht kapiert zu haben, dass das Array pwm_setting die
Helligkeiten darstellt. Willst du die LED 0 auf eine Helligkeit von 34
haben, dann macht die Hauptschleife irgendwann
pwm_setting[0] = 34;
und wenn die LED 3 auf eine Helligkeit von 78 gesetzt werden soll, dann
eben
pwm_setting[3] = 78;
etc. etc.
Und wenn in main beispielsweise LED 0 und LED 7 gegengleich gedimmt
werden sollen, dann beispielsweise eben
....
for( i = 0; i < 255; i++ ) {
pwm_setting[0] = i;
pwm_setting[7] = 255 - i;
_delay_ms( 100 );
}
oder was auch immer du dir an Zusammenhängen ausdenkst. Du schreibst die
entsprechenden Zahlenwerte ins Array pwm_setting an die Index-Position
der jeweiligen LED und der ISR Mechanismus setzt das in eine Helligkeit
um.
Vielen Dank für die schnelle Antwort,
dass im Feld "pwm_setting[]" die 8 PWM-Werte stehen war mir schon klar.
Die zwei auskommentierten Zeilen sind von Versuchen übriggeblieben. der
Rest ist so aus dem Artikel kopiert.
Trotzdem sehe ich jetzt etwas klarer. Aber nochmal mein Beispiel:
Ich habe (erstmal nur) 2 LEDs, die erste wird langsam heller, und danach
wieder dunkler, z.B. gesamte Periode 60s. Die zweite Led beginnt z.B.
10s nach dem Start der ersten heller zu werden, läuft aber schneller
hoch, so dass sie auch 10s eher wieder dunkel ist( Periode dann also
40s).
Da will ich hin, wenn da jemand einen einfachen Lösungsansatz hat, wäre
toll.
Ich stell mir das im Moment etwa so vor:
for(z=0;z<=360000;z++) // das soll später auf 10h gestreckt werden,
//(Aquarienbeleuchtung)
{
pwm_setting[0]=z; // 1. LED läuft sofort hoch
if(z>=100)
{
pwm_setting[0]=(z-100) // 2. LED startet nach 100*100ms=10s
}
my_delay (100);
}
Aber wie schaffe ich es, dass die 2. LED auch früher fertig ist?
Gruß
Sascha
Sascha schrieb:> Trotzdem sehe ich jetzt etwas klarer. Aber nochmal mein Beispiel:> Ich habe (erstmal nur) 2 LEDs, die erste wird langsam heller, und danach> wieder dunkler, z.B. gesamte Periode 60s. Die zweite Led beginnt z.B.> 10s nach dem Start der ersten heller zu werden, läuft aber schneller> hoch, so dass sie auch 10s eher wieder dunkel ist( Periode dann also> 40s).> Da will ich hin, wenn da jemand einen einfachen Lösungsansatz hat, wäre> toll.
Wie praktisch immer, wenn es darum geht Zeitvorgaben zu erfüllen, führt
der Weg über Timer bzw. weg vom Zeitdauer-Denken und hin zum Denken in
Zeitpunkten.
Der Timer fungiert wie der Zeiger deiner Armbanduhr. Um mehrere Dinge
'gleichzeitig' zeitlich zu variieren stellst du dir jede Sekunde neu dir
Frage: Was genau gilt es jetzt, in dieser Sekunde, an den Ausgängen
einzustellen.
> for(z=0;z<=360000;z++) // das soll später auf 10h gestreckt werden,> //(Aquarienbeleuchtung)
Und genau damit liegst du schon falsch. Sobald du hier for-Schleifen
einsetzt um irgedwelche Verläufe zu realisieren, erleidest du
Schiffbruch, sobald die Dinge etwas komplexer werden.
Du brauchst einen 2.ten Timer, der dir sowas wie eine 'Uhr' realisiert.
Und aus der "Uhrzeit" musst du in der Lage sein, zb bei dir die
Helligkeit der einzelnen LEDs zu errechnen.
ISR( ... )
{
zb eine tatsächliche Uhrzeit weiterzählen (weil du Aquarium erwähnt
hast
if( Uhrzeit < 7 Uhr morgens )
Helligkeit aller LED auf 0 setzen
if( Uhrzeit zischen 7 Uhr und 7 Uhr + 255 Sekunden )
Helligkeit LED 0 auf (UHrzeit - 7 Uhr) setzen
if ....
if( UHrzeit > 23 Uhr )
Helligkeit aller LED auf 0 setzen
....
}
Das Prinzip sollte erkennbar sein. Du musst ZU JEDEM BELIEBIGEN
ZEITPUNKT die Helligkeit der jeweiligen LED aus der Uhrzeit (und
sonstigen Dingen wie zb die gerade zu diesem Tag vorliegende
Mondstellung) ERRECHNEN können. Und wenn du das errechnen geschickt
machst, dann ergibt sich daraus, dass zb von 7 Uhr früh bis 7:30 die
LED von 0 bis auf 100% hochdimmen, weil aus deinen Formeln dann eben
sich für alle dazwischen liegenden Sekunden ein jeweils geeigneter
Dimmgrad ergibt.
Und diese Systematik kannst du dann eben auch für 200 LED 'gleichzeitig'
machen. Denn jede LED hat ihren eigenen Formalismus, in den die Uhrezeit
reingeht und aus dem heruaskommt, in welcher Helligkeit genau diese LED
zu genau dieser Uhrzeit (und möglichen anderen Faktoren) zu sein hat.
HInzuzufügen ist noch, dass dieses Zeitpunkt-Prinzip bei dem man aus der
Uhrzeit die Helligkeit errechnet zb bei einem Aquarium gut funktioniert.
Das muss aber nicht so sein. Es gibt auch noch andere Möglichkeiten.
Ausgangspunkt ist wieder der Timer, der eine ISR zb alle 1 Sekunde
aufruft. Aber anstatt aus einer Uhrzeit etwas zu berechnen, kann man
auch hergehen und sich zuvor ausrechnen, welche LED sich im
Sekundenabstand wie verändern muss. In der ISR wird dann nur noch diese
Vorgabe ausgeführt, indem man den Helligkeitswert dieser LED
entsprechend der Vorgabe variiert.
Allen gemeinsam ist aber immer das Prinzip: Dimmschleifen werden durch
einen Timer ersetzt, der in regelmässigen, immer gleichen Zeitabständen
eine ISR aufruft. Und innerhalb der ISR gibt es dann wieder viele
Möglichkeiten, wie es weiter gehen kann. Je nach Aufgabenstellung.
martan schrieb:> hilfreich war für mich dieser Artikel (welche Sprache ist da egal,> bezüglich der Technik):>> http://avr.myluna.de/doku.php?id=de:multiled
Interessante Lösung! wenn ich das richtig verstanden habe, werden die
einzelnen LED-Kanäle nach ihrer Pulsweite aufsteigend sortiert und
gleiche Pulsweiten verschiedener Kanäle zusammengefasst. Die ISR läuft
mit einer festen Frequenz und es werden alle gesammelten Einträge
durchlaufen und gesetzt/gelöscht. Das Ganze ist also unabhängig von der
Anzahl der Kanäle, simpel und genial.
Wie heißt dieser Algorithmus? war mir bisher unbekannt.