Hi, ich möchte gerne 24 leds per pwm ansteuern (8 rote, 8 grüne und 8 blaue). Dazu würde ich den Atmega 8 nehmen. Würde es funktionieren, wenn ich 8 Ausgänge für alle 24 Leds nehme, und dazu 3 andere Ausgänge für die jeweilige Farbe? Mir ist klar, daß dann das pwm verhältnis nichtmehr stimmt, weil ja der Prozessor 2/3 für die anderen 2 Farben opfern muß. Wenn das so funktionieren könnte, dann bräuchte ich aber noch irgendwelche Zwischenspeicher. Gibt es da sowas in der Richtung? Also super wäre ein c-mos mit 20 Pins. 8 Ein und 8 Ausgänge und einen Enable. Wenn der Enable auf high ist, dann sollte er bei den 8 Eingängen einlesen und bei den 8 Ausgängen dasselbe wieder ausgeben. Wenn Enable auf low ist, dann sollte er immer noch ausgeben, aber nicht mehr einlesen. Gibt es einen solchen Baustein? Wäre dann das multiplexen der pwm möglich? Gruß Florian
vielleicht dummer gedanke ... UND Gatter mit 2 Eingängen, 1 Eingang Pin des MC ein eingang "Enable"das muss dann parallel auf alles 8 AND ?? also drei bausteine mit jeweils 8 UN Gatter ?? macht mich bitte nicht gleich alle nieder ;-) .. nur so ein gedanke chris
Man könnte auch drei Schieberegister hintereinanderhängen, dann brauchst du nur 3 Ports. Das Laden von allen Werten braucht dann 24x2 Takte + Overhead 10 Takte, macht 110 Takte, bei 8bit Auflösung kämst du dann noch auf maximal 1kHz mit einem AVR. Je nach Anwendung ist das ausreichend.
Was du suchst heißt Latch. Einfach einen 8-bit Port an 3 Latches legen, jeweils ein Enable-Pin pro Latch und fertig. Macht 11 IOs Gruß Daniel
Könnte ich da einen 4094 nehmen? Wie schnell ist so einer? Geht sich das zeitlich aus?
@jan Hi. Versteh ich das richtig? Hab gerade das Datenblatt vormir. Da steht, das der 4094 2 serielle Ausgänge hat. Damit könnte man mehrere 4094 Kaskadieren. Also würde ich bei meinen Programm im AVR den Timer aufrufen, und dann die einzelnen bytes (pwm) berechnen (ob high oder low). Und dann noch im timer die clock für den 4094 steuern und die 24 Daten übertragen. Was du mit 10 Takte Overhead meinst, versteh ich leider nicht. Gruß Florian
Da steht, das der 4094 2 serielle Ausgänge hat. Damit könnte man mehrere 4094 Kaskadieren. jo.
Das Senden der Daten solltest du nicht per Software machen. Die AtMegas haben eine SPI eingebaut. Da musst du die Daten nur in ein spezielles Register laden und 16 (je nach Einstellung) Takte später ist das Byte gesendet und du kannst das nächste reinladen. Das Überprüfen, ob ein Kanal high oder low ist, kannst du ja machen während die Daten gesendet werden. Das Senden dauert insgesamt 48 Takte, genau wie die Überprüfung. Overhead heißt, was halt sonst noch für die PWM zu machnen ist: - Byte ins serielle Ausgaberegister kopieren - PWM-Daten laden (falls notwendig) - Sprung an den Anfang der Schleife
Hi Jan Mit SPI kenn ich mich leider nicht so aus (eigentlich garnicht) Ist das schwieriger zum programmieren als TWI? Gruß Florian
@ Florian nein, spi ist verhältnismäßig einfach. dadurch das es eine selectleitung gibt, fällt z.b. die adressierung wie bei i2c/twi einfacher aus ;) sprich bauteil selektieren und daten rüberschaufeln (und die clock schön toggeln).
Hi, hab das mal von dem Datenblatt des Atmega 8 abgeschrieben. Doch im AVR studio, simuliert er nicht viel. Fehlt da nochwas? .include"m8def.inc" ldi r16, low(ramend) out spl,r16 ldi r16, high(ramend) out sph, r16 ldi r16,0b00101000 out ddrb, r16 ldi r16, (1<<SPE)|(1<<MSTR)|(1<<SPR0) out SPCR,r16 ldi r16,0b00000101 out SPDR,r16 wait: sbis spsr,spif rjmp wait
HI, habe jetzt bemerkt, das es im AVR Studio nicht geht. Mit VMLAB jedoch geht die SPI Ausgabe. Im Datenblatt vom Atmega 8 steht, das man double SPI Speed bit setzen kann und dadurch doppelt so schnell senden kann. Hat da schon jemand Erfahrungen gemacht? Wie sicher ist die Datenübertragung bei doppelter Geschwindigkeit? Kann es da auch passieren, das dann einzelne bits verschluckt werden? Gruß Florian
Im Prinzip funktioniert das. Kommt halt immer auf deinen speziellen Aufbau an, bis zu welcher Datenrate alles einwandfrei läuft. Einen 74HC595 habe ich schon mit 2 Mbit laufen gehabt. Ansonsten einfach ausprobieren. Wenn es wirklich nicht klappt, kannst du das ja einfach nicht mehr benutzen.
Werde wohl eher einen 74HC595 bestellen, da er ein bisschen schneller als ein 4094 ist. Vielen Dank für eure Hilfe. Gruß Florian
Hi, Habe mir jetzt einen 74HC595 besorgt. Im Datenblatt stehen 2 clock-anschlüsse drin. Einmal der: storage register clock input und einmal der shift register clock input. welchen soll ich da mit sck vom Atmega 8 zusammenschließen und für was ist der andere? Kann mir da jemand helfen?
>> Würde es funktionieren, wenn ich 8 Ausgänge für alle 24 Leds nehme, >> und dazu 3 andere Ausgänge für die jeweilige Farbe? Ja. >> Mir ist klar, daß dann das pwm verhältnis nichtmehr stimmt, weil ja >> der Prozessor 2/3 für die anderen 2 Farben opfern muß. Warum opfern, er pulst jede Farbspalte eben nur maximal 1/3'tel. >> Wenn das so funktionieren könnte, dann bräuchte ich aber noch >> irgendwelche Zwischenspeicher. Gibt es da sowas in der Richtung? Wazu Zwischenspeicher ? Die LED Farbspalten leuchten macimale 1/3'tel der Zeit, ergo sind sie gepulst und ditto erhöst du einfach den Pulsstrom ums dreifache um die gleiche Helligkeit zu erreichen. Deine Schaltung könnte also so aussehen: 3 P-MOSFET's schalten alle Anoden der LEDs getrennt nach Farben. Das sind die Columns. Die LEDs liegen mit Kaothden an einem Treiberbaustein über Widrstände. Den Strom dadrüber stellst du so ein das er ca. das 3 fache der gewünschten "Helligkeit" ergibt. Gängige LEDs vertragen gepulst mit 1/10tel Duty bis zu 100mA. Die Ansteuerung ist nun so das immer nur 8 LEDs einer Farbe leuchten indem nacheinander immer nur einer der MOSFETs angesteuert wird. Ansteuern=multiplexen solltest du mit ca. 50*3 = 150Hz minimium. Gruß Hagen
So, nun möchtest du zb. 64 verschiedene Mischfarben erzeugen. Das entspricht einer Monochromen Farbtiefe von 2 Bits pro Farbe, ergo 6 Bits pro Pixel. Diese 2 Bits müssen in einen Pulsstrom=PWM umgewandelt werden die 3Bit groß ist. Helligkeit PWM-Bits 00 000 01 010 10 101 11 111 Dies *3 für die 3 Farben ergibt ein PWM-Pulsmuster bestehend aus 9 Bits. 9 * 50Hz = 450Hz sollte das Multiplexing erfolgen, minimal. Dies ist aber lässig durch den ATMega8 erreichbar. Als Treiber für die 8 LED-Rows nimmste ein ULN280x. Gruß Hagen
Hallo Hagen Klingt super, so hatte ich es eigentlich vor. Das man die Leds mit einen höheren Pulsstrom betreiben kann, wußte ich nicht. Ich dachte das sind so angaben wie bei den Autoverstärken beim Mediamarkt (Ausgabe max 4x25 Watt RMS und auf der Verpackung steht 4x200 Watt) Hab mir jetzt aber trotzdem mal ein paar Schieberegister besorgt und wow, SPI ist wirklich schnell... Ich dachte, wenn ich da vollgas sende (f osc/2), dann gibt es da sicher Probleme, aber dem ist nicht so. Ich habe eigentlich vor, soetwas zumachen: http://www.litewave.co.uk/scannermvie1.wmv Natürlich wird es nicht so schön und so elegant werden wie das hier, aber mit dem kann ich leben. Hast du eine Ahnung, wie die das gemacht haben? Mit Schieberegistern?? Oder mit deiner Variante, wie du es geschrieben hast? Oder gibt es da noch andere Möglichkeiten? Danke für die Antwort Gruß Florian
Beim SPI kannst du rechnen das maximal F_CPU/2 drinnen ist. Die schnellsten AVRs schaffen 24 MHz, ergo maximal 12MHz SPI. Ein 74HCT595 lacht sich tot bei nur 12MHz, die gehen laut Philips-Datenblatt bis 100Mhz beim HC und 57MHz beim HCT. LEDs haben fast kein Nachleuchten, also müssen sie die LEDs per PWM oder eben variablem Puls-Pausen Verhältniss quasi in der Helligkeit gedimmt haben. Das Video wurde in einer sehr dunklen Umgebung gefilmt, ergo kann man keine Aussage über wie wahre Leuchtstärke der LEDs machen. Bei normalem Tageslicht könnte es durchaus sein das man garnichts mehr davon erkennt. Auf alle Fälle sind es weit mehr als 8 LEDs. Und bei vielen LEDs musst du immer den Verdrahtungsaufwand=Layout in deiner Planung berücksichtigen. Eine LED-Matrix macht also da durchaus Sinn da sie mit weniger "Kabelsalat" auskommt. Dafür muß das Timing dann aber höher sein, was aber für'n AVR kein Problem darstellt. Gehen wir mal von 64 LEDs aus, monochrom. Per SPI an einem 8MHz AVR benötigst du also 128 CPU Takte um die LEDs anzusteuern. Würdest du aber eine Matrix von 16*4 LEDs aufbauen, also 2* 8Bit Port und 4 Columns könntest du schon Pi*Daumen 8 mal schneller multiplexen. Aber wir reden hier von einem visuellen Effekt für Menschen und die können ein langsammes 50Hz Signal nicht mehr als Pulse wahrnehmen. Die obigen PWMs im MHz-Bereich sind also abolut unnötig und überdimensioniert. Ergo kannst du dich auf den Schaltungstechnischen Aufwand konzentieren. Die Shiftregister haben immer dann den Vorteil wenn du sie quasi an den LEDs direkt verbauen kannst. Du könntest dann einzelne Segmente a 8 LEDs bauen die über nur 5 Leitungen untereinander kaskadiert werden. Nämlich Vcc,GND,Clock,Daten,Enable Latch. Du kannst dann solche Module kaskadieren. Pro Modul 8x LEDs, 1x 595, 8x Vorwiderstände. Oder du besorgst dir die STP16c596. Das sind ebenfalls Shiftregister wie der HCT595 haben aber 16 Konstantstromausgänge. Du kannst dann also 16 LEDs ansteuern, OHNE Vorwiderstände und über einen einzigsten Rext Widerstand stellst du den Konstantstrom ein. Ein weiterer Vorteil ist das die Teile bis 100mA pro Ausgang vertragen, die HCT595 vertragen nur 20mA pro Ausgang was aber bei 8x20mA = 160mA bei allen LEDs an ausmacht und über PTot des Chips liegt. Die 20mA sind also eher überdimensioniert. Das Motorola Datenblatt besagt 20mA pro Ausgang als Sink und nur 75mA Icc. Wenn du also nur 4 LEDs am Register leuchten lässt bist du mit 80mA schon über dem maximalem Icc des Chips. Du müsstest also die LEDs mit nur 9mA leuchten lassen damit du auch wirklich alle 8 LEDs leuchten lassen kannst. Damit bekommst du aber keinen sichtbaren Effekt hin, es muß dann schon sehr dunkel sein. Oder du müsstest schon Low-Current LEDs verbauen, die es nur schwer zu kaufen gibt und die es höchstwahrscheinlich nicht in Blau gibt. Du könntest jetzt hinter dem HC595 einen Treiber Baustein setzen, wie dem ULN2805. Oder aber du kannst eine Matrix aufbauen. Der maximale Pulsstrom der meisten LEDs liegt bei 100mA mit 10% Dutycycle. Pulst du also eine LED mit 100mA und 10% Duty dann erscheint die Gesamthelligkeit wie mit 10mA Dauerstrom. (nur Pi*Daumen, ich weiß das sich darüber noch Experten streiten). Es bedeutet aber das du eine Matrix mit maximal 5 Spalten aufbauen solltest damit du mit ca. 20mA Durchschnittsstrom rechnen kannst. Die LEDs werden mit ca. 100mA gepulst in 5 Spalten a 8 Zeilen. Das ergäbe dann 40 LEDs. Schaltungstechnisch also 8 + 5 Leitungen + Vcc + GND. Vorwiderstände benötigst du 8+5 Stück + 1x ULN2805 um die 8 Zeilen zu treiben. Im Grunde baust du ein 8x5 Pixel Display auf, aber eben mit dem Unterschied das alle LEDs in einer langen Reihe liegen statt in einer 8x5 Matrix. Je nach gwünschter Helligkeitsabstufung musst du nun ein 5 fach höheres Multiplexing realisieren. Was aber für ein AVR kein Problem darstellt. Bei diesem Design benötigst du nur noch 5 P-MOSFETs oder PNP Transistoren, 1 ULN Treiber und eben ein Layout das 8+5 Leitungen zu den LEDs ermöglicht. Der Verdrahtungsaufwand könnte sich also erhöhen auf Grund der Anordnung der LEDs in einer einzigsten Reihe. Du solltest dann dein Layout der LEDs so aufbauen das immer die Zeilen mit 5 LEDs nacheinander angeordnet werden. Also zuerst nacheinander 5 LEDs der 1. Zeile dann 5 LEDs der 2. Zeile usw. bis zur 8. Zeile. So minimierst du die Anzahl der nötigen Leitungen für alle 40 LEDs auf 5 Leitungen im Layout. Wie du siehst gibts viele Wege die nach Rom führen, entscheiden musst du dich schon selber. Gruß Hagen
>>Natürlich wird es nicht so schön und so elegant werden wie das hier, >>aber mit dem kann ich leben. Wieso denkst du das ? Erstmal hast du es selber gebaut, das verdoppelt den idellen Wert schonmal. Zweitens ist es im Grunde kein Problem das noch schöner und aufwendiger hinzubekommen, es hängt halt nur vom Geld ab. Gruß Hagen
Vielen Dank für deinen langen, ausfürlichen Beitrag. Hm, das mit den STP16C596 klingt wirklich gut. Dadurch würde man sich wirklich viel Bauteilkram ersparen. Nur bei der Suche nach einem STP16C596 schaut es nicht mehr so gut aus....Conrad, Elcomp, Reichelt, Segor, Ribu......da gibts den nicht. Bei Google schon, aber nur in Amerika. Oder kennst du einen Deutschen vertreiber? Ich vermute mal, da die Dinger doch einiges können und dazu noch schwer zu kriegen sind, werden sie einiges kosten. Ach ja, zum Programm, wenn ich sagen wir mal 8 rote, 8 grüne und 8 blaue Leds nehme: Wenn es ungefähr wie beim Video aussehen sollte, kann ich das dann so machen? Ich nehme den Timer 0 mit CLK 8 und TCNT0 lade ich mit 185. Im timer mache ich dann 3*8 die pwm berechnungen, zwischenspeichern im sram und dann per SPI ausgeben. Bei der SPI-Übertragung den Output Enable des Schieberegisters deaktivieren und danach wieder aktivieren. Im Hauptprogramm lese ich dann alle Zeiten mal meine Tabellen aus. Nehmen wir an: .db 255,0,0,0,0,0,0,255, 255,0,0,0,0,0,0,255, 255,0,0,0,0,0,0,255 ersten 8 rot, die nächsten grün und dann noch blau. Somit würden die ersten 3 und die letzen 3 leds weiß leuchten. Ich will sie aber von 0 aus eindimmen. schleife: lpm temp1,z+;aus der Tabelle laden ld temp2,y; aus dem Sram die momentane Helligkeit laden cp temp1,temp2;vergleichen ob größer,kleiner oder gleich breq fertig;wenn gleich, dann fertig brlo down;wenn kleiner, springe zu down inc temp2;Wenn Tabelle größer als helligkeit momentan rjmp notfertig down: dec temp2;Wenn Tabelle kleiner als helligkeit momentan notfertig: ser merker fertig: st y+,temp2 rjmp schleife Könnte man das so machen, oder tu ich dabei ein bisschen umständlich? Die y Werte im sram sind die, die ich dann im timer für die pwm lade. und tschüss...gähn
>> Bei Google schon, aber nur in Amerika. >> Oder kennst du einen Deutschen vertreiber? Nee, DigiKey hat sie im Program, ca 2 Euro pro Stück, je nach Menge runter bis auf 1.60 Euro. >> Im Hauptprogramm lese ich dann alle Zeiten mal meine Tabellen aus. Nichts mit "Zeiten", dies wird durch "PWM" suggeriert. Sehe es mal eher als "willkürlichen" und möglichst gleichverteilten Pulsestrom an. Es hängt nur von deiner gewünschten Farbtiefe ab, also der maximalen Anzahl an verschiedenen Farben die du erreichen möchtest. Dabei ist zu beachten das "Echtfarben", die Grenze bei dem der Mensch aufhört zwischen den einzelnen Farbabstufungen noch Unterschiede zu erkennen bei 256 Graustufen liegt. In deinem Falle besteht 1 Pixel also aus 3 Bytes Information, jeweils 256 Helligkeiten pro Farbe -> Red,Green,Blue. Ich habe aber die Erfahrung gemacht das mit derzeitigen LEDs schon 64 Farben schwierig zu mischen sind. Angenommen du möchtest 256 Helligkeiten pro Farbe dann benötigst du schon einen Pulsestrom von 256 Bits pro Farbe. Bei RGB also 768 Bits. Das bedeutet das zur Darstellung EINES Pixels in 2^24 möglichen Farben ein Pulsmuster 768 Zyklen lang sein muß. vereinfachen wir mal auf 3 Bit Helligkeit, also 8 Graustufen pro Farbwert, so definiert sich das Pulsmuster auf folgende Weise. Helligkeit Pulsmuster 000 000 0000 001 000 0001 010 000 0011 011 000 0111 100 000 1111 101 001 1111 110 011 1111 111 111 1111 Wie du siehst wird einfach die ON Phase, also die Anzahl der "Zeitscheiben" die eine LED leuchtet direkt aus dem Farbwert ermittelt. Die Kunst ist es nun die ON-Phasen auf die gesammte Zeit so zu verteilen das nach Möglichkeit ein gleichmäßige Muster herauskommt. Man stellt so sicher das die LEDs bei langsammem Multiplexing=Zeitscheiben nicht flackern. Dies könnte so eine Tabelle ergeben: Helligkeit Pulsmuster 000 0000000 001 0001000 010 0010001 011 0101010 100 1010101 101 1101110 110 1111011 111 1111111 Die Frage ist nun wie man sowas in Software möglichst einfach umsetzt ? Wiederum definieren wir erstmal die Designvorgaben. Wir möchten 24 Bit Farbtiefe, also 8Bits pro Farbe. Wir benötigen also einen Pulsestrom pro Pixel von 768 Bits, oder eben Zeitscheiben. Wir wollen eine Bildwiederholrate von 50Hz. Das bedeutet der Timer muß 768 * 50 = 38500 mal pro Sekunde aufgerufen werden. Dies sind also eine Multiplexingfrequenz von 38.5 kHz bzw. alle 26µs muß der Timer aufgerufen werden. Dein DisplayRAM besteht aus 8 Pixel a 3 Bytes pro Pixel benötigt also 24 Bytes. In der TimerISR machen wir nun folgendes, in Pseudocode: DisplayRAM: array[0 bis 7, 0 bis 2] of Byte; Counter: array[0..2] of Byte = (0,0,0); FarbPhase: Byte = 0; procedure TimerISR; var PortValue: Byte; begin // 1.) PortValue = 0; for I = 0 to 7 do begin PortValue = PortValue + PortValue; if DisplayRAM[I, FarbPhase] < Counter[FarbPhase] then PortValue = PortValue or 1; end; // 2.) PORT_LED = PortValue; PORT_MOSFET = 1 shl FarbPhase; // 3.) Counter[FarbPhase] = Counter[Farbphase] + 63; // 4.) FarbPhase = FarbPhase + 1; if FarbPhase > 3 then FarbPhase = 0; end; So nun die Erklärung zum Code: Wir haben zur kompletten Darstellung eines Pixels ein Zeitfenster mit 3 * 256 Zeitscheiben. Dieses Zeitfenster wiederholt sich komplett 50 mal die Sekunde. Wir müssen nun nur noch bestimmmen welches Bit der 768 Bits der Zeitscheiben auf 1 oder 0 gesetzt werden muß. Dazu multiplexen wir immer reihum jeweils eine Zeitscheibe in Rot, Grün und Blau. Unser DisplayRAM in dem du also die Farbwerte der Pixel speicherst besteht also aus einem 2 dimensionalem Array[]. Pixel 3 zb. wäre DisplayRAM[2] da wir ja mit 0-basiertem Index arbeiten. DisplayRAM[2] besteht wiederum aus einem Array mit 3 Bytes. Jeweils ein Byte für Rot, Grün und Blauem Helligkeitswert. Wir benötigen also insgesamt zwei externe Zähler um die aktuelle Zeitscheibe zu bestimmmen. Dies wäre einmal der Zähler FarbPhase, der nur von 0 bis 2 zählen darf, reihum, da wir ja nur die Farben Rot,Grün und Blau haben. Desweiteren den Zähler Counter[] der aus einem Array besteht das für jede Farbe einen Zähler enthält. In TimerISR passiert nun folgendes: 1.) wir berechnen den aktuellen 8Bit PORT Wert an dem unsere LED Zeilen hängen. Jedes dieser Bits addressiert dabei eine der 8 LEDs. Wir gehen mit einer Schleife jedes Pixel im DisplayRAM je nach FarbPhase durch und vergleichen den Helligkeitswert mit dem aktuellen Wert in Counter[FarbPhase]. Sollte der Wert kleiner sein als der Counter[] so schieben wir eine 1 in den PORT ansonsten eine 0. Nach 8 Durchläufen der Schleife haben wir unseren neuen Portwert ermittelt und geben in bei 2.) nun aus. PORT_LED übernimmt die 8 LED-Zeilen und PORT_MOSFET die 3 LED-Spalten. An diesem Port hängen ja die 3 P-MOSFETs oder PNPs die die gemeinsammen Anoden je nach Farbe der LEDs ansteuern. Es kann also imm nur einer der 3 Farben leuchten. Ab diesem Moment wird das neue Muster angezeigt. Bei 3.) müssen wir nun die Zähler updaten. Zuerstmal den aktuellen Zähler zur Farbe inkrementieren. Der Trick ist nun NICHT mit +1 zu inkrementieren sondern absichtlich die Byte-Zähler überlaufen zu lassen. Die Zähler sind ja Bytes und bei einem Inkrement um +63 würde also nach 4 Durchläufen der Zähler schon überlaufen. Dies ist aber beabsichtigt denn so wird sichergestellt das ein gleichmäßig verteiltes Pulsemuster unabhängig vom Helligkeitswert entsteht. Die LEDs leuchten also immer gleichmäßig verteilt in ihrer Helligkeit. Du kannst auch andere Inkrements als 63 ausprobieren. Wichtig ist nur das due ein Inkremement aussuchtst das sicherstellt das nach 256 Durchläufen alle Werte von 0 bis 255 im Zähler gestanden haben. Beispiel: Inkrements wie +2,+4,+6,+8 usw. sind absolut schlecht da ja beginnend bei 0 nach x Schritten ein Überlauf im Zähler enstünde der sofort wieder bei 0 wetiermacht. Alle ungeraden Zählerstände würden also niemals eintreten. Schlecht also, da es die Farbtiefe reduziert. Aber Inkrement wie +5,+7,+11,+73 usw. also Primzahlen sind eine absolut sichere Wahl. Denn mit diesen ist sichergestellt das erst nach 256 mal +Primzahl wieder der Zähler auf 0 geht. Es werden also in Sprüngen a +Primzahl alle Werte zwischen 0 bis 255 berechnet, und dies ohne großen zeitlichen Aufwand. Bei 4.) wird nun noch die FarbPhase inkrementiert. Beim nächsten Aufruf der TimerISR wird also die nächste Farbe angesteuert. Es wird also immer reihum Rot,Grün,Blau,Rot,Grün,Blau usw. Zeitscheiben gemultiplext. Mit diessr Methode wird also sichergestellt: - das alle Farben zeitlich gleichmäßig verteilt angesteuert werden - das der Pulsestrom möglichst gleichmäßig verteilt über alle 768 Zyklen ON und OFF Phasen hat. - der maximale Dutycylce den eine LED ON sein kann exakt 33.3% beträgt. Dies bedeutet das du den LED Strom von vornherherein um das 3 fache erhöhen musst. Zb. bei 90mA wären die LEDs effektiv so hell wie bei 30mA Dauerstrom. Der Algo. stellt nun sicher das niemals diese 33.3% Dutycylce überschritten werden kann. Gruß Hagen
Achso einen Vorteil des Algos. habe ich noch vergessen: Er verteilt den Impulsstrom der LEDs gleichmäßig. Würde man es einfacher machen und zb. in Zeitscheibe Nummer 0 alle LEDs leuchten lassen deren Helligkeit > 0 ist. So würden defacto ALLE LEDs aufleuchten und somit 8 * 90mA Strom fließen. Dafür würde aber in Zeitscheibe 255,254,253 fast niemals LEDs leuchten da ja dort nur LEDs mit maximaler Helligkeit ON wären. Die Impulsstrom-Belastung wäre also sehr ungleichmäßig verteilt. Mit obigen Algo. würde aber dies nicht passieren, da wir ja in größeren Schritten alle Zustände der Counter[] durchlaufen. Der durchschnittlsiche Impulsstrom verteilt sich also sauber über das komplette Zeitfenster das sich 50 mal pro Sekunde wiederholt. Man kann also NICHT mehr von PWM reden. Eher von einer zeitlich zerstückelten PWM bei der das Verhältnis von ON zu OFF Phasen sich gleichmäßig über das komplette Zeitfenster verteilen. Gruß hagen
Sehe gerade noch ein par fehler: 1.) Counter : array[0 bis 2] = (0,1,2); Die Zähler für die 3 Farben sollten mit unterschiedlichem Startwert arbeiten. Dies stellt sicher das bei gleichem Helligkeitswert sich denoch die Zeitscheiben in denen eine LED leuchtet unterschiedlich sind. Somit wird der Impulsstrom wiederum gleichmäßiger verteilt. 2.) FarbPhase = FarbPhase + 1; if FarbPhase > 3 then FarbPhase = 0; das muß natürlich if FarbPhase > 2 then FarbPhase = 0; heissen. Gruß Hagen
>>Im timer mache ich dann 3*8 die pwm berechnungen, zwischenspeichern >>im sram und dann per SPI ausgeben. Nichts mit zwichenspeichern ;) das ist meistens absolut unnötiger Resourcenverbrauch. Du kannst obigen Pseudocode ganz einfach umbauen für deine Shiftregister. Dies geht indem du in der TimerISR immer 1 Schritt vorraus bist. D.h. am Anfang der TimerISR wird das Latch der Shiftregister an deren Ausgänge übernommen. Du pulst also kurzzeitig den LE + /OE Eingang der Shiftregister. Beide Eingänge sollten verbunden sein. Ist LE aktiv, sprich die Latches werden an die Ausgänge gelegt so ist /OE automatisch inaktiv und die Ausgänge sind High-Z. Ist LE inaktiv so ist /OE demzufolge aktiv und an den Ausgänge liegt das aktuelle Bit-Muster an. Somit hats du über diese EINE Steuerleitung gleich zwei Funktionen realsiert. Du kannst einerseit die Latches im Hintergrund befüllen während an den Ausgängen noch das aktuelle Bitmuster anliegt. Und andererseits kannst du die Ausgänge komplett Dunkelschalten und gleichzeitig die neuen Daten übernehmen. Dies setzt natürlich vorraus das die LEDs von Plus->Anode->Kathode->Shiftregister angeschlossen sind, die Register ziehen=versenken also den Strom, sie "sink-en". Natürlich musst du die P-MOSFET nun auch zu diesem Zeitpunkt setzen. Nachdem nun der Latch gepulst wurde wird normal in der TimerISR bei 1.) weitergemacht und der neue PORT Wert berechnet. Diesen gibts du an das SPI weiter das nun beginnt die Latches der Register zu füllen. Am Schluß wird bei 3.) und 4.) weitergemacht, die Zähler also ge-updatet. Du machst also alles Live in der TimerISR und benötigst kein Zischenspeicher mehr. Wozu auch ? Den Aufwand der "Dekodierung" hast du sowieso, ob nun in der TimerISR direkt oder über einen Zwischenspeicher. In deinem Falle macht das aber keinen Unterschied. Klar, falls man nur "Standbilder" ausgibt und mit viel mehr LEDs arbeiten muß so das sich die Multiplexing-Frequenz drastisch erhöht, könnte ein Zwischenspeicher wieder sinnvoll werden. Gruß Hagen
Hi Hagen. Kannst du dich bitte mal bei E-mail bei mir melden? Gruß Florian
Danke Hagen, super Artikel. So etwas müsste in die Code-Sammlung bzw. Artikel-Sammlung.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.