Sinusfunktion, LED Dimmen

Gast #2540102
Lesenswert?

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_t k;
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
Gast #2540270
Lesenswert?

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
Gast #2540286
Lesenswert?

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.
Gast #2540465
Lesenswert?

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.
Gast #2540985
Lesenswert?

Hallo,

natürlich wäre eine Tabelle das einfachste, aber ich möchte es gerne so 
lösen...
1
 while(1)
2
 {
3
  
4
  uint8_t k;
5
  //for(k=1; k < 360; k++)
6
  //{
7
   k = 45;
8
   i_ct = 511.0*(sin(0.785)+1.0);
9
   
10
   
11
   if ((i_ct<530)  && (i_ct>500)) { // for debugging
12
   OUTPT |= (1<<LED2);
13
   //}
14
   
15
   _delay_ms(2); // time between two increments of OCR1A (brightness increments)
16
   
17
  }
18
   
19
 }
k ist also typ int. Habe den sinuswert als bogenmaß mal direkt 
eingegeben... So funktinoiert es, aber warum anders (wie oben) nicht?

alxy
#2541009
Lesenswert?

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"
Gast #2541020
Lesenswert?

Danke. Habs jetzt geändert, den Datentyp un es funkltioniert (fast)
1
 while(1)
2
 {
3
  
4
  uint8_t k;
5
  double n;
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
#2541164
Lesenswert?

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.
Gast #2541195
Lesenswert?

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
#2541203
Lesenswert?

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.
Gast #2541657
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren