Forum: Mikrocontroller und Digitale Elektronik Wie kann ich Eingangswiderstand für Lichtorgel regeln


von Daniel K. (kloeggaa)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
Bis dato bin ich durch andere Beiträge hier im Forum immer zum Ziel 
gekommen, jedoch bin ich nun mit meinem Latein am Ende. Die 6 Kanal 
Lichtorgel (Beitrag "[C] AVR-Lichtorgel per FFT MEGA8 32 644") habe ich 
nachgebaut und sie läuft wunderbar auf meinem atmega88. Nun will ich das 
Eingangssignal mit einem Digital-Potentiometer AD5220 so steuern, dass 
der Eingang des atmega88 immer gut ausgesteuert ist. Dieser wird 
anstelle des 10K drehpoti (R1) verbaut, siehe Schaltplan im Anhang. Die 
Lichtorgel soll unabhängig von der Lautstärke der Musik gleich leuchten.

Wenn das Eingangsignal übersteuert ist, soll der Widerstand vergrössert 
werden, fällt das Signal unter ein bestimmtes Level, soll er verringert 
werden. Ein Durchschnittswert der letzten n-Zyklen wäre wahrscheinlich 
eine gute Variante.
Da LED_PORT nur in ISR gesetzt werden kann, da es sonst zu langsam wird, 
müssen auch hier die Pins für den Widerstand gesetzt werden. Laut 
Datenblatt des AD5220 zunächst CLK high und U/D so setzten wie es 
gewünscht wird (R grösser, oder kleiner), dann CLK low und der 
Widerstand schaltet. Ich würde über globale Variablen registieren ob CLK 
beim letzten mal auf high gesetzt wurden und geschaltet werden kann, bzw 
ob beim letzten mal geschaltet wurde und CLK wieder auf high gesetzt 
werden kann. Den Port auslesen funktioniert leider auch nicht, weil das 
ganze dann zu langsam für die FFT läuft.

Nun die konkreten Fragen:

1. Wie finde ich heraus ob das Eingangsignal übersteuert, bzw zu klein 
ist?
2. Gibt es einen Trick wie man das Schalten des Widerstandes eleganter 
machen kann?

von Stefan F. (Gast)


Lesenswert?

Übersteuert ist es, wenn dein ADC den maximalen Wert liefert, also 1023.

Eleganter fände ich eine analoge Regelung. Ich bin mit dieser Schaltung 
sehr zufrieden: http://stefanfrings.de/audio_limiter/index.html

von Daniel K. (kloeggaa)


Lesenswert?

Extern geht es sicher auch, aber ich habe ja schon alles. Ich würde es 
gern in dem bestehenden Programm lösen. Das muss doch auch mit dem 
buffer funktionieren. Mir ist allerdings ein Rätsel, wie die FFT mit nur 
einem int funktioniert. Bis jetzt bin ich mit copy paste ziemlich weit 
gekommen, muss jetzt aber das Programm besser verstehen um den 
Widerstand stellen zu können.

Das ist capture_wave

void capture_wave(int16_t *buffer, uint16_t count) {
  ADMUX = _BV(REFS0)|_BV(ADLAR)|_BV(MUX2)|_BV(MUX0);

  do {

    ADCSRA = 
_BV(ADEN)|_BV(ADSC)|_BV(ADATE)|_BV(ADIF)|_BV(ADPS2)|_BV(ADPS1);

    while(bit_is_clear(ADCSRA, ADIF));
    *buffer++ = ADC + INT16_MIN;
  } while(--count);

  ADCSRA = 0;
}

und weiter unten im main steht dann:
    capture_wave(capture, FFT_N);
    fft_input(capture, bfly_buff);
    fft_execute(bfly_buff);
    fft_output(bfly_buff, spektrum);

von Daniel K. (kloeggaa)


Lesenswert?

Habe gerade rausgefunden, dass *buffer++ den pointer schiebt und den 
Wert ablegt. Ich dachte es wird der Wert zum alten addiert. Jetzt 
verstehe ich auch, dass die FFT funktionieren kann.
Leider haben sich damit meine beiden Fragen noch nicht beantwortet, ich 
bin aber noch voller Hoffnung, dass mir jemand helfen kann.

von Helmut L. (helmi1)


Lesenswert?

Ganz einfach, so wie man es auch Analog machen wuerde.

Zuerst das Signal gleichrichten mit abs(x)
Dann Tiefpassfiltern mit einem IIR Filter .

Old =  (old*k) + (new*(1-k))

k = Filterfaktor (0..1)
new = neuer MEsswert vom ADC (mit abs ) gleichgerichtet
old = der gefilterte Wert.

Dann den gefilterten Wert gegen zwei Grenzen pruefen.
Wird die unter Grenze unterschritten muss man den Pegel erhoehen.
Wird die obere Grenze ueberschritten muss man den Pegel verkleinern.

von Stefan F. (Gast)


Lesenswert?

Ach so, ich dachte es ginge Dir darum, Übersteuerung der OP-Amps und des 
ADC zu verhindern.

von Joe F. (easylife)


Lesenswert?

Für solche Anwendungen (Lichtorgel) gibt es auch Schaltungen, die dir 
den Eingangspegel automatisch in einen sinnvollen Bereich regeln.
Nennt sich dann "automatic gain control" oder AGC.

Beispiel:
http://electronicdesign.com/site-files/electronicdesign.com/files/archive/electronicdesign.com/files/29/6272/figure_01.gif

: Bearbeitet durch User
von Manfred (Gast)


Lesenswert?

Daniel K. schrieb:
> Eingangssignal mit einem Digital-Potentiometer AD5220 so steuern, dass
> der Eingang des atmega88 immer gut ausgesteuert ist. Dieser wird
> anstelle des 10K drehpoti (R1) verbaut, siehe Schaltplan im Anhang.

Der OP im Eingang hat eine Verstärkung um 10. Für eine elektronische 
Regelung würde ich dort anfassen, am Pin 6 bzw. parallel zu R4 + C2.

Poti R1 bleibt wie es ist, damit kann man manuell den Pegel erstmal grob 
in den gewünschten Bereich holen.

von Daniel K. (kloeggaa)


Lesenswert?

Manfred schrieb:

> Der OP im Eingang hat eine Verstärkung um 10. Für eine elektronische
> Regelung würde ich dort anfassen, am Pin 6 bzw. parallel zu R4 + C2.

Ein guter Punkt. Kann man gut machen, allerdings funktioniert das mit 
dem Dreh-Poti R1 im Moment gut. Ich werde das mal im Hinterkopf behalten 
falls der Range nicht reicht und ich mehr Verstärkung brauche.

von Daniel K. (kloeggaa)


Lesenswert?

Ich habe es nun so gemacht, dass ich das Maximum von capture suche und 
anhand dessen den Widerstand stelle, ohne Filter. Geht ziemlich gut, nur 
hätte ich besser einen nicht linearen Widerstand genommen, da irgendwann 
zwischen zwei Zuständen hin und her geschaltet wird. Ich belasse es bei 
dem Drehpoti, damit kann ich auch die Helligkeit indirekt einstellen und 
auch die Lichter kann man so auch ganz abschalten. Vielen Dank an alle 
aber trotzdem. Wieder was gelernt :)

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.