Hi. Kann der AVR Logarithmus rechnen? Ich möchte damit meine LEDs vernünftig ein und ausdimmen können. Oder hat jemand von euch noch eine bessere Idee dafür? Mein ziel ist es das sie eben gleichmäßig dimmen.
Wie willst du die dimmen? Nimm einfach PWM, das ist das einzige, was man machen kann.
Ja klar PWM das dimmen an sich ist nicht das Problem. Da eine LED aber nicht linear gleich leuchtet ist das mein Problem. Ich kann also nicht einfach x = x + 1 machen um sie gleimäßig eindimmen zu lassen.
Klar kann der AVR rechnen. Aber der Platzbedarf dafür übersteigt den der 256-Byte-Tabelle, die du statt dessen verwenden solltest.
Ich verwende für meine LED folgende Tabelle mit 64 8bit-PWM-Werten: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 25, 28, 30, 33, 36, 39, 42, 46, 49, 53, 56, 60, 64, 68, 72, 77, 81, 86, 90, 95, 100, 105, 110, 116, 121, 127, 132, 138, 144, 150, 156, 163, 169, 176, 182, 189, 196, 203, 210, 218, 225, 233, 240, 248, 255 Bei kleinen Helligkeiten ist das natürlich nicht optimal, da man die ersten 3-4 Schritte deutlich sehen kann. Etwas besseres ist mir aber auch noch nicht eingefallen.
Das selbe problem habe ich auch. in einer anwendung wollte ich verschiedene helligkeitsstufen regeln lassen. aber der srung von 0 zu 1 war da schon zu krass. Hatte damals nicht versucht was es für einen unterschied macht, mal von 8 auf 9 oder 10 bit zu gehen
Hallo, ich hatte dasselbe problem, habe aber mich schon lange nicht mehr darum gekümmert. ich wollte eine rgb-led ansteuern (3 * pwm) eine 16-bit-pwm ist mir zu langsam, da sieht man die leds "blinken", außerdem wollte ich einen tiny2313 benutzen und die haben nur 2 16-bit-pwms. (ok, plus zwei mal 8-bit-pwm) meine idee war sowas wie ein "2-stufiges pwm": ein 8-bit-pwn "direkt" auf die leds und dazu parallel ein zweites über einen vorwiderstand. (ströme: direkt ca. 30mA, vorwiderstand: ca. 30mA/256=ca.117µa) ob das wohl funktionieren könnte ? was ich auch noch nicht probiert habe, ist ein 10- oder 12-bit-pwm per software, das könnte den "einschaltsprung" evtl. heruntersetzen und dabei noch schnell genug sein. gruß klaus
also am besten geht einen PWM im mainloop ohne timer da kannste dann auch unedlich viele haben, hab das mal für nen LED Weihnachtsbaum gemacht sah ganz ordentlich aus.
Hallo, @ Laeubi: war da ich gemeint ? ich hatte natürlich ein 8-bit-pwm in software ausprobiert, (habe ich nur vergessen zu erwähnen). [ja im "mainloop" und ohne timer. den wollte ich später für die farb-umschaltung verwenden] das war in der allerersten "rgb-led-version" mit einem 90s1200 (der ohne ram, ohne rs232, fast ohne alles). dadurch weiß ich, dass es bei 8-bit-pwm einen "einschalt-helligkeits-sprung" bei leds gibt. deshalb habe ich den 16-bit-hardware-pwm bei einem tiny2313 probiert. ergebnis: zu langsam. dann kam was dazwischen und das wars erstmal. daraufhin folgten ein paar unausgegorenen ideen: siehe mein letztes posting (so heisst das doch, oder ?). aber ausprobiert habe davon ich noch gar nichts. Frage: LED-weihnachtsbaum ? waren das led-kerzen ? würde mich interessieren, wie das gemacht wurde (mittlere helligkeit plus/minus zufall oder wie ?) aber das passt wahrscheinlich nicht hierher. ###################### @ Markus: mir ist noch eingefallen, ich habe damals das "logarithmus-problem" so gelöst/angenähert, dass ich einfach immer ein viertel des aktuellen led-ist-wertes addiert/subtrahiert habe (vorsicht bei der grenze gegen null: 2 2mal geshiftet ist null ==> durch 1 ersetzen, sonst wird der istwert nie null) an eine tabelle habe ich gar nicht gedacht. müsste mir das zu denken geben...? (aber wahrscheinlich sind eh schon alle probleme gelöst)
Also den Weihnachtsbaum hatte ich 4 verschieden Farbige LEDs halt in form eines bauemes, und dann immer auf/ab gedimmt so das erst eine farbe an, dann die nachste bsi alle aufegedimmt waren, dann das gleiche Spiel umgekehrt, mittels Poti konnte man die Geschwindigkeit regeln. PWM funktioniert ja über die Pulsbreite, also würde ich einfach den Wert für die SoftPWM auf 16bit erhöhen und mit ca 4mhz arbeiten das sollte dan flimmerfrei sein, mit Timer hab ich das damals auch nicht wirklich gut hinbekommen, entweder es hat geflackert, oder der AVR war die ganze Zeit in der Timer ISR das der ADC Wert nicht wirklich ausgewertet werden konnte und solche Späße, ich hab da natürlich nicht wirklich auf exacte Stufen gearbeitet daher waren auch ein paar Sprünge drinnen die aber für den Effekt vernachlässigbar waren.
Hi, wie wäre es denn, wenn man zwar ein 16bit-pwm nimmt, aber an dessen Ausgang noch einen Kondensator schaltet. Je nach Dimensionierung sollte damit das Flackern der LEDs einigermaßen gut unterdrückt werden können. Gruß Y.d.k.J
hi, @ Laeubi: klar, bei der geschwindigkeit wäre die timer-isr das "hauptprogramm". aber ich habe eh das ohne timer probiert (wie gesagt: ich wollte den einzigen timer für die farben verwenden) in software wäre ein 16-bit-pwm zu langsam, da müsste man den zähler hochzählen, für drei kanäle 16 bit vergleichen und die port-ausgaben machen. schon ein 16-bit-zähler alleine hat bei einem 8mHz-quarz eine freq. von ca 122Hz (8MHz/65536). das sieht man deutlich! selbst eine freq. von (ca.) 500 Hz kann man sehen wenn man hin- oder wegschaut. das sind leds und keine glühlampen. (ja ja, das hatte ich mir auch überlegt. nur: wo gibts rgb-rainbow-glühlampen [das war eine rhetorische frage]) drei einzelne lampen haben keinen gemeinsamen "brennpunkt" deshalb: vielleicht 10 oder 12 bit. und: die kleinen AVRs, die ich kenne haben nur 2 mal 16-bit-hardware-pwm, deshalb die "überlegung" mit den zwei "parallelen" 8-bit-hardware-pwms. oder vielleicht 8-bit-hardware-pwm und in software 3-4 bit parallel mit widerständen dazu, je nach übrigen portpins... @Y.d.k.J: ja, das habe ich auch probiert. aber so direkt am avr-port klappt das nicht. und direkt an der led bräuchte man mehr als 4700µf, denn genau das hab ich probiert. auch probiert habe ich: einen transistor zur stromregelung (npn, "strom-widerstand" am emitter) und die basis-spannung über pwm steuern, aber das ist "furchtbar schwierig" einzustellen, das muss ja genau 0,6 bis 4,2 volt sein (oder so ähnlich, je nach I, Uf, Ubc und Ri am emitter). so krumme widerstände gibts gar net! ach ja, wegen des basisstroms habe ich dann auch 'nen darlington probiert... also irgendwann hab ich's aufgegeben. (vorerst jedenfalls) danke erstmal für die antworten, ich wollte eigentlich Markus nur einen kleinen tipp geben und vielleicht erfahren wie's denn geklappert hat. und dann labere ich über meine eigenen schwierigkeiten... ich probiers einfach mal sobald mein rechner+stk200 wieder aufgebaut sind.
Hallo! Jaja, das üblich Thema LEDs-Dimmen. :-) Genau da hab ich auch mal so ein paar kleine Experimente gemacht, da ich einfach keine zufriedenstellende Lösung im Netz gefunden habe... Die Beste Lösung, die ich bisher hinbekommen habe, ist folgende: * 8-Bit-Timer mit Compare-Match-IRQ * zunächst sehr kleinen Compare-Match Wert, der aber bei jedem IRQ Aufruf verlängert wird. * Ein Regsiter als "PWM-Zähler" * Bei jedem Aufruf des Timers LED-Helligkeits-Wert mit "PWM-Zähler" vegleichen und entsprechend die LED ein oder ausschalten Der Trick dabei ist nämlich der, daß bei sehr kleinen Helligkeitswerten die Zeitdauer des IRQ-Aufrufes (und damit das ausschalten der LEDs) sehr kurz ist, mit jedem erneuten Aufruf (=Helligkeits-schritt) aber verlängert wird. Sozusagen eine pwm, bei dem die Zeitspanne der einelnen Schritte unterschiedlich lang ist. Ich hoffe, man versteht, was ich meine? Ich kanns schlecht erklären... Hier mal ein kleiner Auszug der Assembler-IRQ-Routine: -----CUT --------- ;****** IRQ TIMER 1 Compare Match **** timer1irqA: ; *** Register-Werte sichern *** in itemp, SREG ; Status-Register... push itemp ; ...auf dem Stack sichern ;** Dauer bis nächsten aufruf verlängern ldi itemp2, mpwm ; letzter durchlauf? (mpwm = maxpwm, s.o.: equ) cp pwm, itemp2 ; vergleichen brne t1alonger ; ...wenn nicht - sprung. Sonst: clr pwm ; ...pwm wieder auf 0 setzen, und ldi ZL, $10 ; ...Z-Register... clr ZH ; ... auf Anfangswert setzen rjmp t1aset t1alonger: ; noch nicht letzter durchlauf, dann: adiw ZH:ZL, $10 ; wert hinzuaddieren t1aset: out OCR1AH, ZH ; Timer 1A Compare HighByte out OCR1AL, ZL ; Timer 1A Compare LoByte led1: cp pwm, led1 ; wenn led1... brlo led1an ; ...größer als pwm, dann led einschalten brsh led1aus ; ...gleich oder größer pwm, dann ausschalten rjmp led2 ; ...sonst weiter mit led2 led1an: cbi portd,0 ; LED0 einschalten (lo-aktiv, clear bit) rjmp led2 ; ...sonst weiter mit led2 led1aus: sbi portd,0 ; LED0 ausschalten (hi-inaktiv, set bit) led2: (......) -----CUT --------- Bei diesem Codebeispiel wird bei jedem Aufruf der Timer-Compare-Wert um $10 verlängert, insgesamt 16mal (mpwm-Wert wird per equ. im Programmkopf festgelegt), dann wieder zurückgesetzt auf den Anfangswert (=kleineste Helligkeitsstufe). So hab ich es geschafft, mit 16 (oder auch mehr, = mpwm-Wert) Helligkeitsstufen halbwegs gleichmäßig zu dimmen, besonders der Einschaltmoment ist schön "weich", Stufe 1 glimmt nur. Zeitdiagramm: |--1--|-----2----|-------3-------|----------4--------|---.... Der nächste Verbesserungsschritt wäre jetzt, den jeweils neuen Wert des OCR1A aus einer Tabelle zu lesen. Aber eigentlich war es auch so augenscheinlich schon relativ linear. Ich hoffe, mein Codeschnippsel ist halbwegs verständlich. Den kompletten Codes müßte ich erst überarbeiten, da sehr viel irrelevantes Zeug dazwischen ist, was für die Dimm-Funktion nicht relevant ist und das ganze nur unübersichtlich macht. Gruß, Andi.
Beim 16bit-PWM kann man doch auch nur z.B. 12 Bits verwenden, um eine ausreichend hohe Ausgangsfrequenz zu erreichen. Das ganze läuft dann nur in der Hardware. Clear Timer on Compare Match (Auto Reload) Variable PWM Period Ich weiß, das PWM-Kapitel ist harte Kost, sollte aber noch mal durchgekaut werden.
was bedeutet eigentlich das "*abo*" ??? das habe ich jetzt so oft gelesen...
Hallo, kann mir jemand hilfen, bei LED einschalten und ausschalten eines Microcontroller zu programmieren. danke
Schau bitte ins Turorial auf dieser Seite. Wenn du dann noch Fragen hast: Bitte konkrete Fragen stellen!
@frage: Vermutung: Mit abo will der Poster wohl "per Email über Antworten auf diesen Beitrag informieren" anwählen, was aber nur geht, wenn man einen Beitrag postet...
Konkrete Fragen,wie geht das mit farben? also einschalten, ROT und Grün, 2 farben, falls ok ist dann grün, falls error dann rot. wie kann man sowas programmieren? danke
Du hast 2 Leds an 2 Ausgabepins deines Prozessors hängen. Jeden der beiden Pins kannst du unabhängig vom anderen auf 0 oder 1 setzen (eingeschaltet oder ausgeschaltet). Je nachdem brennt dann die an diesem Pin angeschlossene Led oder sie brennt nicht. Noch mal: Wie man eine Led anschliesst und sie programmtechnisch zum Leuchten bringt, steht im Tutorial. In der Link-Leiste links, gaaaaanz nach oben scroll, der 2. Link.
kannste mir sagen ob du ein paar links über C programmierung von einem LED, wäre sehr gut, dankeschön,
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial Und dann vielleicht noch: www.fielmann.de (Duck und wech...)
#include <avr/io.h> int main() { DDRB = 0xFF; // B-Port auf Ausgabe PORTB = 0xAA; // das Bitmuster 10101010 am B Port ausgeben } wenn du jetzt an den B-Port 8 Leds anschliesst, dann brennen 4 davon. Je nachdem wie du die Leds anschliesst brennen entweder die Leds an B0, B2, B4, B6 oder die an B1 B3,B5, B7. Diese ersten Schritte kannst du genausogut in Assembler machen. Das hat nämlich den Vorteil, dass es 1) mit AVR-Studio eine IDE dafür gibt, die du bei der Programmierung in C sowieso wieder brauchen wirst 2) Du ein Verständnis dafür bekommst, was den im µC so alles abläuft 3) Es ein minimalistissches (aber nichts desto trotz gutes) Tutorial auf dieser Site gibt. 4) Du nicht durch Konfigurationsfehler abgelenkt wirst 5) Die ersten Programme genausogut in Assembler wie in C geschrieben werden müssen 6) Du lernst Datenblätter zu lesen und die Informationen in Programme umzusetzen ohne dass da noch ein C Schicht dazwischen ist, die Verwirrung stiften könnte 7) der Umstieg nach C für größere Programme um einiges leichter fällt, da du bereits direkt an der Hardware programmiert hast 8) ...
Hallo Markus! Das ist relativ einfach zu realisieren. Bei 64 verschiedenen Zuständen kann man einfach ein Quadrat benutzen. x = x + 1 ist nicht so gut (es müsste x++ heissen). Die Formel würde dann wie folgt lauten: y = x * x / 16 Somit kommst du auf fast das gleiche Ergebnis wie Jan M. Gruß Guido
Ich steuere mit einem ATTiny26 4 RGB LEDs mit 12bit PWM an. Dazu verwende ich einen Software PWM, der aber auf einem einzigen Hardware-Timer basiert. Der Trick dabei ist, dass ich keinen richtigen PWM verwende, sondern die PWM Periode in Teilperioden folgender Länge einteile: 4096 2048 .... 16 8 4 2 / 1 . Für die langen Perioden verwende ich den Hardware-Timer, der mir rechtzeitig einen Interrupt generiert. Die kurzen Perioden werden im letzten Interrupt durch software delays generiert. Nun muss nur in jeder Periode jede LED entsprechend eines Bits ihres Helligkeits-Wertes angeschaltet werden. In der längsten Periode also das MSB, in der kürzesten das LSB. Damit die Interrupts möglichst kurz werden wird die etwas aufwändige Bit-Extraktion im Mainloop erledigt. Verwendet wird damit etwa die Hälfte der 128 Byte RAM, etwa 250 Wörter Programmspeicher (natürlich in Assembler) und benötigt etwa 10% der Rechenzeit. Daneben konnte ich also noch gut eine Exponentialfunktion, sowie einen Sinus implementieren. Diese basieren auf einer relativ kleinen Lookuptable (etwa 8 mal 4byte Einträge) aus dem Programmspace, die dann quadratisch iterpoliert werden. Dazu wird ein software 8bit Multiply verwendet. Damit ist der tiny26 dann ziemlich voll ausgelastet in allen resourcen, jedoch gibt das einen flackerfreien, beliebig dimmbaren 12-fach led driver. Die PWM-Auflösung liesse sich auch noch anpassen. Nun bin ich noch damit bweschäftigt, einen wirklich gleidchmässigen Farbwechsel hinzukriegen, ohne Helligkeitsschwankungen in der Nähe der Primärfarben. Das ganze ist jedoch in Assembler gehalten.
Ich benutze eine HSB2RGB-Umrechnung und habe den Eindruck, dass die Helligkeit relativ konstant ist. Zumindest in meinem Fall habe ich nur bei blau eine etwas stärker wahrnehmbare Schwankung. Ich hab gerade erst angefangen, also korrigiert mich wenn ich mich irre: Der Tiny26 wird mit der HSB2RGB-Wandlung vermutlich ein Problem haben, der Flash meines ATMega8 ist mit 3 Hardware-PWMS, 3 Drehgebern auslesen, der Wandlung und noch ein paar Kleinigkeiten schon zu etwa 40% voll (in C).
Stimmt, ich habe auch schon HSB sowie HSV probiert, die Helligkeit ist tatsächlich nicht so ein problem (kommt vor allem auf die relative helligkeit der drei leds an). Eigentlich wollte ich sagen, dass die farbänderung nicht gleichmässig ist in der nähe der primärfarben. Ich denke das liegt an der linearen Hue konversion (nach Wikipedia). Deshalb der Sinus, damit wollte ich die lineare konversion ablösen, habe ich aber noch nicht implementiert. Die Daten zur Auslastung de3s Tiny26 sollten in etwa stimmen. Ein Teil ist sicher die Assembler Programmierung: zum Vergleich: mein Software-PWM interrupt dauert exaket 23 clock-cycles (ohne aufruf-overhead). In C dauert alleine die Sicherung der Register etwa 64 cycles. Mein PWM hat eine Frequenz von etwa 64Hz (2^23Hz = 8MHz / (2^12 * 32=2^5) => 2^6=64Hz). Dabei dauert der kürzeste PWM impuls 32 cyles, für Maximale Auflösung von 16bit PWM liesse sich das auf 2 cyles, dem absoluten minimum reduzieren. Das bedeutet pro Konversion stehen 2^17 = 131072 cycles zur verfügung. Die interrupts für die 8MSb kosten ca 8*30=240 cycles, der interrupt für die 4LSb dauert ca 512 cycles, insgesamt also weniger als 1% ( => fehler in meiner schätzung im letzten beitrag). Je einmal exponentialfunktion wird gebraucht für den Brightness wert jeder der 4 RGB Kanäle macht 4*160 = ca 500 cycles. Beachte, mein exp verwendet eine statische software multiplikation, die daher in wenigen cycles durchgeht, die dynamischen sind 31 cycles. Einmal Sinus pro Hue wert gibt 4* ca 500 = 2000 cycles. Nicht zu vergessen das bit extrahieren aus den RGB werten und einfüllen der Tabelle für die PORTA & PORTB Werte dauert ca 12*12*8 ~ 1000 cycles. Alles in allem also ca. 5000 cycles, also insgesamt ca 5% (das ist ja weniger als ich dachte :-). Bleibt genügend Zeit für IO, Pseudorandom - generation inklusive software 16bit multiply usw. Was lernen wir daraus? Assembler ist nach wie vor ein extrem leistungsfähiges mittel, wenn man mit sehr beschränkten resourcen etwas erreichen will. Allerdings war das mein einziges projekt in assembler, seiter fast nur noch C :-).
Falls interesse besteht, kann ich die erwähnten routinen in der codesammlung bereitstellen. Der code selber ist im moment soweit ich weis nicht lauffähig, da ich mitten im programmieren stehen geblieben bin. Ausserdem ist er praktisch nicht kommentiert, wer sich jedoch dafür interessiert sollte die relevanten sachen schon finden können.
Hallo LEDs dimmt man am besten indem man den Strom Regelt. Das hießt du solltest dir eine Spannungsgesteuerte Stromquelle bauen z.B. mit einem OP. Also einfach die PWM mittels eines Tiefpasses glätten dieses signal auf den OP. Das hat den Vorteil das die LED nun mit konstanter Spannung betrieben wird und dadurch kein Flackern auftreten kann.
Wenn PWM schnell genug ist flackerts auch nicht, also wozu der zusätzliche Schaltungsaufwand ?
Ich suche auch nach eine guten Lösung um eine LED möglichst linear zu dimmen. Hat schonmal jemand eine Gammakorrektur verwendet und kann Erfahrungen äußern? Von Maxim gibts dazu eine Application Note: http://www.maxim-ic.com/appnotes.cfm/appnote_number/3667
Hallo. Ich habe folgendes Anliegen: Prinzipiell geht es um einen R/G/BW Dimmer für 1W LEDs, der über DMX 512 steuerbar sein soll. Für jede Farbe soll ein DMX Kanal zuständig sein und ein weiterer Kanal soll die Gesamthelligkeit aller Farben steuern. Die Auflösung der Kanäle sollte bei 10 Bit liegen und das PWM Signal sollte eine Frequenz um die 30kHz haben. Mit welchen MCUs ist solch ein Vorhaben realisierbar, wer kann mir einen Code schreiben ( soll auch nicht umsonst sein) Ich selbst habe keinerlei Programmierkenntnisse und bin für jede Hilfe dankbar.
Hallo, Sorry, dass ich den alten Beitrag hochhole, aber ich hab eine Frage zu dem Thema. Ich verwende einen ATMega168 und bin gerade dabei, ein DALI-EVG zu bauen. Da ich alles streng nach Norm programmieren, will ich auch das logarithmische Dimmen mit 254 Stufen berücksichtigen. Nur, wie mach ich das mit dem 168er? Gibts dazu Ansätze. Die 64 Stufen, die ich mit einer 8bit-Auflösung schaffen würde sind zu gering. Hat da jemand schon Erfahrungen gesammelt? Übrigens: Angesteuert werden RGB-LEDs. mfg Andy
@Andy (Gast) >logarithmische Dimmen mit 254 Stufen berücksichtigen. Nur, wie mach ich >das mit dem 168er? Gibts dazu Ansätze. Siehe LED-Fading. > Die 64 Stufen, die ich mit einer >8bit-Auflösung schaffen würde sind zu gering. Wer sag das? MFG Falk
Naja, das sagt die DALI-Norm. Ich muss 254 Stufen log. schaffen - wie soll das mit 8Bit gehen?
@ Andy (Gast) >Naja, das sagt die DALI-Norm. Link? < Ich muss 254 Stufen log. schaffen - wie >soll das mit 8Bit gehen? Gar nicht. Selbst mit 16 Bit PWM wird das knapp. Siehe Artikel. MfG Falk
Hi, der Beitrag hier ist schon etwas länger nicht mehr erweitert worden, aber ich hoffe das mein "Beitrag" dennoch für Leute die über die Suche hierher gelangen hilfreich sein kann. (muss dazu sagen, hab selber erst vor ein paar Tagen mit einem atmega16 und nen pollin eval board begonnen) das Problem mit dem Dimmen ist ja, wie hier an vielen stellen schon festgestellt, das wir die helligkeitsdifferenzen bei niedrigen Helligkeitenswerten besser war nehmen als bei höhen Helligkeitswerten. Der verlauf ist aber bekanntlich nicht linear, sondern logarithmisch. Ich hab aus verschiedenen Beispielen hier im Forum nun meine LED gedimmt bekommen, ich hab eine Tabelle mit Werten wie oben benutzt. Nun wollte ich aber selber solche Tabellen machen können, abhängig von pwm bitbreite und Anzahl der schritte. Leider hab ich hier aus Arbeit nur Java, aber das nach C zu protieren sollte ja nicht das Problem sein ;) Das Programm liefert dann "fast" Copy'n'Paste fertige Tabellen. Ich hab den Logarithmus zur Basis E genommen. Hoffe das Hilft jemanden...
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.