Hallo,
ich habe vor, mittels Avr-gcc (Das Tutorial hab ich gelesen) und C eine
entsprechend dimmbare LED zu programmieren. (Auf Pollin Eval Board)
Funktioniert auch soweit, allerdings versuche ich das ganze, als das Aus
und Einschalten (Dimmen) jetzt als Sinuskurve zu verwirklichen. Dazu
habe ich folgenden Code:
1
while(1)
2
{
3
4
uint8_tk;
5
for(k=1;k<360;k++)
6
{
7
i_ct=511*(sin(k/180*M_PI)+1);
8
9
10
if(i_ct<500){// for debugging
11
OUTPT|=(1<<LED2);
12
}
13
14
_delay_ms(2);// time between two increments of OCR1A (brightness increments)
15
16
}
17
18
}
Leider funktioniert das nicht ganz. Die LED leuchtet einfach die gannze
Zeit. (Der entsprechende PIn wird vorher auf 1 gestellt)
Wäre für einen Tip dankbar,
alxy
Und wo in dem Beispiel setzt du OCR1A auf den gewünschten
Helligkeitswert?
Lass uns mal einfacher anfangen: Wie genau dimmst du eigentlich die LED?
Mittels Timer oder mittels Software?
Es wäre wohl besser die Werte des Sinus in einer Tabelle zu speichern in
der genauigkeit in der du es haben willst!
Dann das Array durchlaufen (Zeitabstände mit Timer(besser) oder delay)
und am ende wieder bei 0 anfangen...
In abhängigkeit von dem Wert den du da hast musst du die Led per PWM
dimmen...das geht wohl am besten mit einem (Deutlich schnelleren Timer,
wahrscheinlich auch mit der eingebauten PWM (da kenn ich mich nicht
aus)).
LG Alexx
alxy schrieb:> Dazu> habe ich folgenden Code:
Mit Sicherheit nicht. Ohne den Rest des Programmes ist das von dir
gelieferte ziemlich witzlos. Über den Unsinn der Nutzung von
Floatingpointarithmetik, insbesondere Winkelfunktionen aus math.h auf
einem AVR lasse ich mich lieber nicht aus.
alxy schrieb:> i_ct = 511*(sin(k/180*M_PI)+1);
Das kann ja nichts werden: k/180 ergibt entweder 0 oder 1. Sin 0/PI = 0.
Also ist dein Ergebnis immer 511.
k kann übrigens nie 360 erreichen.
alxy schrieb:> sin(..)
und
> _delay_ms(2)
passen zeitlich nicht so richtig zusammen. Wenn du den Prozessor
unbedingt beschäftigen willst, muß der PWM-Takt per Timer erzeugt werden
und langsamer als die längste Berechnung des neuen Wertes sein.
Abgesehen davon eignet sich die Sinusfunktion wegen der logarithmischen
Helligkeitswahrnehmung nicht wirklich als Modulation. Im positiven
Bereich des Sinus werden die Helligkeitsänderungen kaum wahrnehmbar
sein.
alxy schrieb:> i_ct ist übrigens typ double...
i_ct ist ziemlich uninterressant.
k ist interessant
uint8_t k;
k/180
k nimmt Werte von 1 bis 359 an. Damit ergibt k / 180 entweder 0 (für
alle Werte von k von 1 bis 179) bzw. 1 (für k gleich 180 bis 359). Damit
wird der komplette Ausdruck
k/180*M_PI
entweder 0 oder M_PI und für beide ist der Sinus jeweils 0.
FAQ - Der Abschnitt 2, über "Datentypen in Operationen"
Im Übrigen:
Du schaltest die LED nie wieder aus.
Im Laufe einer Schwingung wird (wenn du die Berechnung korrigierst) die
LED irgendwann mal eingeschaltet, und ab da brennt sie dann dauernd.
Danke. Habs jetzt geändert, den Datentyp un es funkltioniert (fast)
1
while(1)
2
{
3
4
uint8_tk;
5
doublen;
6
for(k=1;k<361;k++)
7
{
8
n=k*0.01745;
9
i_ct=511.0*(sin(n)+1.0);
10
11
12
/*if ((i_ct<530) && (i_ct>500)) { // for debugging
13
OUTPT |= (1<<LED2);
14
}*/
15
16
_delay_ms(2);// time between two increments of OCR1A (brightness increments)
17
18
}
19
20
}
Sie geht von "halban" (511) auf ganz an(1022) und dann langsam bis
aus(0) (natürlich nicht ganz aus, aber annähernd), aber dann springt sie
wieder auf halban (511). Das wiederholt sdich dann natürlich.... sieht
man auch auf dem oszilloskop
alxy
alxy schrieb:> Mh, eine Frage habe ich doch noch. Ließe sich die performance der> berechnung noch optimieren, wenn ich zB einen Ton erzeugen will?>> alxy
Sorry aber liest du eigentlich auch manchmal was man dir schreibt? Es
tut mir leid aber dein Programm ist absoluter Blödsinn. Funktionieren
mag es in Ansätzen aber das ist nicht nach den Regeln der Kunst. Nicht
umsonsnt gibt es hier Artikel zum LED-Fading. Das was du machst ist
Arbeitsbeschaffungsmaßnahme für deinen Mikrocontroller. Wenn du
optimieren möchtest, dann solltest du mal entsprechende Artikel lesen.
Zum Thema Sound - andere Baustelle aber sicherlich nicht auf diesem
Wege. Sorry für die harten Worte. Muss aber sein.
Harte worte müssen sein ... ;)
Aber ich will es eben nicht mit einer Tabelle machen, sondern so. Wenns
nicht geht, auch oaky. Hätte ja sein können, dass man durch ausnutzung
bestimmter Modi da noch etwas optimeiren kann und so die Frequenz
erhöhen kann. Dann würde das mit dem Ton auch klappen ;)
alxy
alxy schrieb:> Harte worte müssen sein ... ;)>> Aber ich will es eben nicht mit einer Tabelle machen, sondern so.
Du kannst noch so fest mit dem Fuss aufstampfen und "Ich will aber"
schreien. Davon wird die Arbeit, die der µC mit Floating Point
Arithmetik hat auch nicht weniger.
Wenn du optimieren willst, dann musst du dort ansetzen, wo optimieren
etwas bringt. In deinem Fall ist das die Floating Point Arithmetik und
ganz speziell die Berechnung des Sinus zur Laufzeit. Du willst
optimieren? Dann werde diese Berechnung los.
"Wasch mir den Pelz aber mach mich nicht nass" funktioniert nun mal in
der Realität nicht.
wieso?? Geht doch!
(Quelle:
http://www.amazon.de/Frottee-Trockenshampoo-fresh-200ml/dp/B0012S7IXG)
Duckundwech
Scherz beiseite: SIN auf dem uC ist ein absolutes nogo. Nur weil's der
Compiler unterstützt, muß das noch lange nicht sinnvoll sein. Ich würde
an Deiner Stelle nicht mal ansatzweise drüber nachdenken.
Ralf
Mit einem externen Quartz und den entsprechenden Fusebits ließ sichd as
ganze noch um den Faktor 16 optimeiren...
Trotzdem habe ich am Ende dann trotzdem zur Tabelle gegriffen :P Damit
war der Ton wenigstens zu hören.
alxy