www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR RGB-LED PWM MUX


Autor: Roberto (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
habe vor mein Zimmer mit RGB-LEDs zu beleuchten, habe dem entsprechend 
auch schon so ziemlich alle Beiträge gelesen die es hier gibt...

Das was ich anders habe als bei den anderen Projekten ist, das ich pro 
LED (rgb) ein Poti habe der an jeweils an einem AD-Wandler hängt.
Danach soll der Wert (1:1) als PWM wieder ausgegeben werden, aber nur 
auf einem PWM-Port. Ein MUX schaltet zwischen den 3 LEDs.

Habe das soweit auch alles geschafft. Mein Problem ist, dass wenn ich 
einen Poti hochdrehe, ab einer gewissen Stelle eine andere LED mit 
aufleuchtet, obwohl ich den Poti dazu garnicht verändert habe....

Habe dann erstmal die Potis und den AD-Wandler weggelassen um zu 
überprüfen ob es vielleicht am MUX liegt und alle LEDs mit einem festen 
wert über den MUX angesteuert, aber der hat seine arbeite richtig getan!
Daher denke ich das es irgendwie an den AD-Wandlern liegt?!

Benutze übrigens einen ATMega16 dafür mit 12Mhz

Hoffe ich konnte mein Problem soweit gut erklären....

Grüße
Roberto

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Äh, "PWM multiplexen", wie soll das gehen?
Wenn Du ein PWM signal per Multiplexer an die LEDs
weitergibst wirst Du nie 100% Helligkeit erreichen.
Oder verstehe ich Dich falsch?
Schick mal Deinen Schaltplan.

Autor: so vieleicht besser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PORTA = pwm[pwm_count];
  cli();
  OCR1BL = werte[pwm_count][0];
  OCR1BH = werte[pwm_count][1];
  pwm_count++;
  if(pwm_count > 2) pwm_count=0;
  sei();

Autor: Roberto (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, also das mit der Helligkeit ist sicher richtig, aber macht sich 
nicht soo bemerkbar
Also wie gesagt, am Multiplexer liegt das nicht....
Leider geht trotzdem noch die eine LED mit an, wenn ich den Poti einer 
anderen LED hochdrehe....
Weiß jemand woran es liegt und was ich dagegen tun kann?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Roberto (Gast)

>Weiß jemand woran es liegt und was ich dagegen tun kann?

Dein Programm ist sehr merkwürdig.

cli() und sei() in einer ISR ist ziemlich sinnlos bis gefährlich.
Dein Umschaltung der AD-MUX ist falsch. Das muss eher heissen.

BYTE ad[3] = {0, 1, 2};      //AD-Wandler

Denn nur so misst du nacheinander den ADC-Kanal 0, 1, und 2.
Das mmit einem Array zu machen ist aber wie man sieht eher sinnlos.
Das merkwürdige trennen von   ad_count++; und der Überlaifprüfung ist 
keine gute Idee, spätestens wenn deine Programme grösser werden schiesst 
du dir damit ins Knie.
Seinen eigenen Datentyp Byte zu erfinden ist Unsinn, schau dir mal 
stdint.h an, dort ist alles schön und standardisiert verfügbar.

Probiers mal so
#include <avr/io.h>
#include <avr/interrupt.h>

//Globale Variablen
uint8_t pwm_count, ad_count, werte[3][2];
uint8_t pwm[3] = {0, (1<<PA3), (1<<PA4)};  //Ports f?r LED-MUX

//PWM-Interrupt
ISR(TIMER1_COMPB_vect) {

  PORTA = pwm[pwm_count];
  OCR1BL = werte[pwm_count][0];
  OCR1BH = werte[pwm_count][1];
  pwm_count++;
  if(pwm_count > 2) pwm_count=0;
}


//AD-Interrupt
ISR(ADC_vect)
{
  werte[ad_count-1][0] = ADCL;
  werte[ad_count-1][1] = ADCH;
  ADMUX = ad_count;
  ADCSRA |= (1<<ADSC);
  ad_count++;
  if(ad_count > 2) ad_count = 0;
}

int main()
{

  //Richtungskonfiguration der Ports
  DDRA = (1<<PA3) | (1<<PA4);  //Port A 3/4 als Ausgang f?r MUX definieren
  DDRD = (1<<PA4);        //PWM Port OC1B


  ad_count = 1;
  pwm_count = 1;
  
  //PWM OC1B gew?hlt mit 10 Bit, Vorteiler 1 f?r PWM OC1B
  TCCR1A = (1<<WGM11) | (1<<WGM10) | (1<<COM1B1) | (1<<COM1B0);
  TCCR1B = (1<<CS10) | (1<<WGM12);
  
  TIMSK = (1<<OCIE1B);      //Interrupt einschalten
  
  
  //Vorteiler bei 12 MHz auf 187.5 kHz stellen, Interrupt ausl?sen wenn fertig, Wandler einschalten
  ADCSRA = (1<<ADIE) | (1<<ADPS2) | (1<<ADEN);
  
  
  sei();              //Interrupts allg. aktivieren
  
  
  ADMUX = ad[0];          //AD-Wandler 0 w?hlen, ADLAR=0

  ADCSRA |= (1<<ADSC);      //AD-Wandlung starten

  OCR1BH = 0x00;
  OCR1BL = 0x00;
  
  PORTA = pwm[0];

  //Unendlich-Schleife
  
  while(1)
  {}
  
  return 0;
}

MFG
Falk

Autor: Robert L. (robertino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Falk: Vielen Dank, aber leider hat sich an dem Problem damit nicht 
verabschiedet :(
Aber der Quellcode ist schonmal etwas kleiner geworden...

Hab eben mal das Oszilloskop an die Stuerports vom MUX getan, und nun 
weiß ich denk ich woran es liegt, aber nicht wie ich es beheben kann.
Und zwar habe ich die PWM invertiert laufen, "Top" heißt das meine ich, 
also so das wenn ich ne 0 drauf gebe der 5V ausgibt und bei 255 (8 Bit) 
dann 0V (RGB-LED hat gemeinsame Anode)
Also wenn ich nun an das Poti hochdrehe, wird dadurch ja das Signal des 
PWMs immer kleiner, und irgendwann dann mal so klein, das der MUX es 
nicht mehr schafft mitzu schalten....
Das war meine Überlegung, kann das sein?
Wenn das richitg ist, was könnte ich dagegen tun?

Grüße und vielen dank (schonmal) an alle!!!

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eben, ein PWM Signal zu Multiplexen ist quatsch...
Welchen Vorteil versprichst Du Dir davon?
Bitte poste doch mal Deinen Schaltplan.

Autor: Robert L. (robertino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso sollte das quatsch sein?
Wenn man nur einen PWM-Port zur verfügung hat ist das doch ne top sache!
Das läuft zZt ja nur auf dem Mega16, soll aber später auf dem Tiny2313 
(vormals AT90S2313) laufen, und der hat nur einen PWM.

Autor: Robert L. (robertino)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Der Lageplan

Autor: Jens W. (dermoench)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eine alternative wäre Soft-PWM:
http://www.mikrocontroller.net/articles/Soft-PWM

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Gast (Gast)

>Eben, ein PWM Signal zu Multiplexen ist quatsch...

Nöö, das passt schon. Sowas macht man auch, wenn man eine LED-Matrix 
dimmen will. Been there, done that.

MFg
Falk

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Roberto Leonardi (robertino)

>Dateianhang: Plan.JPG (18,2 KB, 2 Downloads)

Mal abgesehen vom Hinweis auf Bildformate, sind solche 
hingeschmierten Schaltpläne nicht sehr viel wert. Hast du das dritte 
MUX-Eingangspin fest auf 0V gelegt? Und auch alle anderen Eingänge auf 
festes Potential?

MFG
Falk

Autor: Robert L. (robertino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiß das das nicht viel Sinn macht, hatte eigentlich auch nicht vor 
dieses hier hochzuladen, da es einfach ein zu simpler Schaltplan ist...
Ja, alle anderen Pins liegen auf festem Potential.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, Muxen macht Sinn, wenn man zu Anzeigezwecken eine
RGB LED ansteuern will.

Aber für den genannten Zweck der Zimmerbeleuchtung gehe ich
davon aus, dass man die volle Leistung der LEDs ausnutzen will / muss.

Und ab hier macht das Multiplexen meiner Meinung nach
keinen Sinn mehr, da man ja nie eine 100% An-Phase je LED
realisieren kann.

Jede einzelne RGB LED ist also max. 1/3tel der Zeit an.
Um dies zu kompensieren müsstest Du in den An-Phasen den Strom 
entsprechend erhöhen. Ob dies einer Power LED (alles andere macht
für eine Zimmerbeleuchtung imo keinen Sinn) so zuträglich ist?

Da Dein Kontroller ja vermutlich nicht mehr viel mehr macht als das
RGB PWM Signal zu erzeugen, überlege Dir ob Du nicht eine Soft PWM 
realisierst.

Grüße

Autor: Robert L. (robertino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm ja, das habe...das hört sich gut an, allerdings habe ich noch nicht 
ganz verstanden wie das funktioniert...werd ich mich wohl mal reinlesen
Wieso ist denn eine LED beim Multiplexen max nur 1/3tel an? Der MUX 
wartet ja bis das Signal komplett rüber ist und schaltet dann erst um. 
Und das bei 12MHz, da drüfte es doch keine Verluste geben, oder doch?

Vielen Dank für euren gazen Beiträge!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Roberto Leonardi (robertino)

>Wieso ist denn eine LED beim Multiplexen max nur 1/3tel an?

Das ist das Prinzip von Multiplexen, siehe auch LED-Matrix.

>Und das bei 12MHz, da drüfte es doch keine Verluste geben, oder doch?

;-)
Denk mal in RUHE drüber nach und nicht solche Schnellschüsse aus der 
Hüfte.

MfG
Falk

Autor: Sven H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dein Problem liegt im Prinzip der A/D Wandlung:
Du schaltest den Kanal des A/D Mux um und liest direkt danach den Wert 
des Kanals ein!
Das funktioniert nicht, da im A/D Wandler sich die Sample & Hold 
Schaltung erstmal umladen muss,
bis du den A/D Vorgang starten darfst.

Beispiel:
Poti 1: 5V
Poti 2: 0V

Zuerst hat sich der Kondensator auf 5V geladen. Anschliessend soll er 
sich in einem
Taktzyklus sofort auf 0 Volt entladen? Das kann nicht funktionieren. 
Deshalb wird ein
Wert bei ca. 1V o.ä. eingelesen.
Schau dir mal das Datenblatt zum Prozessor an. Dort sind die Timings 
beschrieben!

Autor: Robert L. (robertino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Falk
Ah ok....jetzt hab ichs auch ;)


@ Sven
Ich habe mir irgendwie schon immer gedacht das es an den AD-Wandlern 
liegt...könnte ich das Problem denn dann so lösen, das ich da einfach 
ein delay reinbastel im Interrupt vom AD-Wandler?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Roberto Leonardi (robertino)

>liegt...könnte ich das Problem denn dann so lösen, das ich da einfach
>ein delay reinbastel im Interrupt vom AD-Wandler?

Patsch
Delays haben im Interrupt nichts zu suchen!

Einfach den ADC richtig ansteuern und es läuft. Den Interrupt brauchst 
du dazu nicht. Lies den ADC ohne interrupt in der Hauptschleife aus, 
dort ist dann ausnahmsweise auch ein Delay zulässig.

MFG
Falk

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Sven H. (Gast)

>Du schaltest den Kanal des A/D Mux um und liest direkt danach den Wert
>des Kanals ein!

Nöö, er list das Ergebnis der letzten Umwandlung ein. Was wahrscheinlich 
fehlt ist ein Kondensator von 2..100nF an dem AD-Eingangspin.

MfG
Falk

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei eine Soft PWM erzeugst Du softwaregesteuert die
jeweiligen Signale an drei Pins, je ein Pin pro
LED. Da das Auge recht träge ist reicht imo eine
PWM Cycle Frequenz von z.B. 100hz, vermutlich auch weniger,
dann kann es aber vorkommen, dass das Auge bei Bewegung
ein Flackern wahrnimmt.
Dass heißt, dass Du immer dann einen Timer Interrupt
auslösen musst, wenn sich einer der PWM Ausgangszustände
ändern soll. Im Interrupt änderst Du dann den Zustand des Pins.
Außerdem berechnest Du die Zeit bis zum nächsten Wechsel und
setzt den Timer entsprechend.

                           1    1
            2    5       9 0    2
t(ms)  0    5    0       0 0    5 usw
        ___                ___
R _____|    |______________|    |______________ 25%

        ________           ________
G _____|         |_________|         |_________ 50%

        ________________   ________________
B _____|                 |_|                 |_ 90%


Das Abtasten der AD Eingänge kannst Du sogar noch deutlich
langsammer machen z.B. nur alle 200ms und die Werte in globale
Variablen speichern. Damit hast Du insgesamt recht entspannte
Verhältnisse und bekommst 100% LED Power je LED und hast
keine Probleme mit der AD Wandlung der Potispannungen.

Grüße

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und das ganze spart dann auch noch den Multiplexer...

Autor: Robert L. (robertino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Gast
Das hört sich gut an...dann werd ich das wohl mal testen!
Meld mich bei Problemen wieder ;)
Vielen Dank

@Falk
Hab einen Kondensator und eine Spule am Aref Pin, wie es im Datenblatt 
es Mega16 drin steht....
Soll ich pro Poti einen 100nF C dran tun, oder wie?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Roberto Leonardi (robertino)

>Soll ich pro Poti einen 100nF C dran tun, oder wie?

Ja.

Autor: Robert L. (robertino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm...
wegen dem TP-Verhalten?
Meine da liegt ja eigentlich nur Gleichspannung an....

Autor: Sven H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Falk:

  ADMUX = ad_count;
  ADCSRA |= (1<<ADSC);


Das beißt sich direkt untereinander!

Autor: Sven H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
(Da gehe ich jede Wetter drauf ein, dass das Problem darin liegt)

Autor: Robert L. (robertino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll ich denn sonst dazwischen machen? Leerzeilen?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.