Forum: Mikrocontroller und Digitale Elektronik Stufenloses Led-Fading Atmega32


von Dario (Gast)


Lesenswert?

Hi

Ich möchte ein Led-Fading mit einem ATmega32 bauen welches keine für das 
menschliche Auge sichtbare Stufen hat. Bei dem Code von hier: 
http://www.mikrocontroller.net/articles/LED-Fading
kann man die Stufen gut erkennen. Kennt jemand einen Code bei dem die 
Stufen nicht sichtbar sind?
(Der Code sollte in C sein)
lgd

von Mike (Gast)


Lesenswert?

Dario schrieb:
> Kennt jemand einen Code bei dem die Stufen nicht sichtbar sind?

Kannst du nicht selber einen Timer programmieren?
Nimm einen 16-Bit Timer und überlagere ein Dither-Signal.

von Christian K. (christiankarle)


Lesenswert?

Hallo Dario,

Du könntest folgendes tun:

Du lässt einen Timer immer so lange laufen bis er einen bestimmten Wert 
erreicht hat. Dieser bestimmte Wert löst dann alle z.B. 1/300 Sekunden 
einen Interrupt aus. In diesem Interrupt schaltest Du dann einen Pin 
deines ATmegas
an oder aus und generierst somit eine Software PWM.

Ich denke Du möchtest ja darauf hinaus eine Soft PWM zu generieren oder 
?.

Dein ATmega enthält außerdem 4 fertige PWM Kanäle...

: Bearbeitet durch User
von Christian K. (christiankarle)


Lesenswert?

Schau mal das habe ich gerade in meinem Sammelsurium gefunden. Habe ich, 
glaube ich damals auch in irgend einem Forum gefunden...

Wenn Du fragen zum Programmtext hast dann frag :)



#define F_CPU 8000000L
#define F_PWM 100
#define PWM_STEPS 256
#define PWM_DDR DDRD
#define T_PWM ( F_CPU / ( F_PWM * PWM_STEPS ) )


#if ( T_PWM < ( 93 + 5 ) )
#error T_PWM zu klein, F_CPU muss vergroessert werden oder F_PWM oder 
PWM_STEPS verkleinert werden
#endif

#include <stdint.h>
#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint8_t pwm_setting[ 16 ];

ISR ( TIMER1_COMPA_vect )
{

    static uint8_t pwm_cnt = 0;
  volatile uint8_t tmp1 = 0;

  OCR1A += ( uint16_t ) T_PWM;

  if ( pwm_setting[ 0  ] > pwm_cnt ) tmp1 |= ( 1 << 0 );
  if ( pwm_setting[ 1  ] > pwm_cnt ) tmp1 |= ( 1 << 1 );
  if ( pwm_setting[ 2  ] > pwm_cnt ) tmp1 |= ( 1 << 2 );
  if ( pwm_setting[ 3  ] > pwm_cnt ) tmp1 |= ( 1 << 3 );
  if ( pwm_setting[ 4  ] > pwm_cnt ) tmp1 |= ( 1 << 4 );
  if ( pwm_setting[ 5  ] > pwm_cnt ) tmp1 |= ( 1 << 5 );
  if ( pwm_setting[ 6  ] > pwm_cnt ) tmp1 |= ( 1 << 6 );
  if ( pwm_setting[ 7  ] > pwm_cnt ) tmp1 |= ( 1 << 7 );

  PORTD = tmp1;

  if ( pwm_cnt == ( uint8_t ) ( PWM_STEPS - 1 ) )

  pwm_cnt = 0;

  else

  pwm_cnt ++;
}

int main ( void )
{

  PWM_DDR = 0xFF;

  TCCR1B = 1;
  TIMSK |= ( 1 << OCIE1A );

  sei();

  while( 1 )
  {

  }
}

von Falk B. (falk)


Lesenswert?

@ Dario (Gast)

>menschliche Auge sichtbare Stufen hat. Bei dem Code von hier:
>http://www.mikrocontroller.net/articles/LED-Fading
>kann man die Stufen gut erkennen. Kennt jemand einen Code bei dem die
>Stufen nicht sichtbar sind?
>(Der Code sollte in C sein)

Was gefällt dir nicht an der 16 Bit Version? Und sag ja nicht, dort 
erkennst du Stufen.

Wem die 120Hz zu wenig sind, kann immer noch auf 16 MHz gehen, dann hat 
er 240 Hz. Oder etwas weniger als 16 Bit, z.B. 12 oder 14 Bit PWM 
machen, das reicht immer noch und man kommt mit der PWM-Frequenz weiter 
hoch, wenn man WIRKLICH so photosensibel ist.

von Mike (Gast)


Lesenswert?

Falk Brunner schrieb:
> Und sag ja nicht, dort erkennst du Stufen.

Ich weiß ja nicht, was du mit den Augen hat, aber zumindest einen Sprung 
von 0 auf 1 wird (fast) jeder erkennen und bei darauf folgenden unteren 
Helligkeitsstufen sieht es nicht viel besser aus. Du unterschätzt die 
Dynamik vom Auge.
Das sieht natürlich anders aus, wenn man die LED bei zusätzlicher 
Raumbeleuchtung betreibt, die den Arbeitspunkt fürs Auge festnagelt.

von Dirk K. (dekoepi)


Lesenswert?

Ein schnell gestricktes "Dim-Blink"-Beispiel mit Arduino-GUI - keine 
Ahnung, wo ich das her hatte oder ob sogar selbst getackert ;) :
1
/*
2
  DimBlink
3
  Fades the LED in and out, infinitely.
4
  This example code is in the public domain.
5
 */
6
 
7
// Pin 13 has an LED connected on most Arduino boards.
8
// give it a name:
9
int8_t ledPin = 13;
10
int8_t my_delay = 0;
11
int8_t border = 25;
12
int8_t steps = 1;
13
14
// the setup routine runs once when you press reset:
15
void setup() {                
16
  // initialize the digital pin as an output.
17
  pinMode(ledPin, OUTPUT);     
18
}
19
20
// the loop routine runs over and over again forever:
21
void loop() {
22
  my_delay += steps;
23
  if (my_delay == 0 || my_delay == border) steps = -steps;
24
  
25
  digitalWrite(ledPin, HIGH);   // turn the LED on (HIGH is the voltage level)
26
  delay(my_delay);               // wait
27
  digitalWrite(ledPin, LOW);    // turn the LED off by making the voltage LOW
28
  delay(border-my_delay);               // wait
29
}

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@ Mike (Gast)

>> Und sag ja nicht, dort erkennst du Stufen.

>Ich weiß ja nicht, was du mit den Augen hat, aber zumindest einen Sprung
>von 0 auf 1 wird (fast) jeder erkennen

na dann mal los, zeig mal wie man es besser macht!

> und bei darauf folgenden unteren
>Helligkeitsstufen sieht es nicht viel besser aus. Du unterschätzt die
>Dynamik vom Auge.

Nö.

>Das sieht natürlich anders aus, wenn man die LED bei zusätzlicher
>Raumbeleuchtung betreibt, die den Arbeitspunkt fürs Auge festnagelt.

Und was machst du? Erstmal 30 Minuten Dunkelanpassung?
Leute gibt . . .

von Mike (Gast)


Lesenswert?

Falk Brunner schrieb:
> Und was machst du? Erstmal 30 Minuten Dunkelanpassung?

In einer halben Stunde paßt sich das Auge über 11 Größenordnungen an. Da 
muss die 16-Bit PWM noch ein bisschen üben...

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.