Arduino PWM mit 16BIT

Hallo, gibt es eigentlich ne Möglichkeit, den Arduino umzurüsten oder um AUsgänge/Board zu erweitern, so dass man mit 16BIT statt nur 8 BIT das PWM SIgnal steuern kann?

Gruß Thorsten

Das hängt wohl von deiner Frequenz ab, die du erzeugen willst. Wenn es nicht zu schnell sein muss, kannst du dir in einem Timer Interrupt einen Zähler mit 16 Bit einrichten und die PWM damit generieren.

Gruß, Thomas

Hi, welche Frequenz meinst du genau? Die Geschwindigkeit mit der ich das Ausgangssignal verändere? (also Steps/Sekunde?) Kannst du mir das ein wenig näher erklären mit dem Timer Interrupt oder kann ich das irgendwo nachlesen?

Ziel ist es, dass ich meine LED Lampe "analoger" dimmen möchte, sprich die digitalen 8BIT sind schon sehr ruckartig, insbesondere bei niedrigen Werten sieht man den Dimmvorgang in einzelnen Schritten. Bei 16Bit hatte ich ja statt 256 insgesamt 65536 Abstufungen zur Verfügung. Geht das mit dem TImer Interrupt?

Gruß Thorsten

currymuetze: Hallo, gibt es eigentlich ne Möglichkeit, den Arduino umzurüsten oder um AUsgänge/Board zu erweitern, so dass man mit 16BIT statt nur 8 BIT das PWM SIgnal steuern kann?

Hallo,

Das hängt zum Teil davon ab, welchen Controller du auf deinem Arduino Board hast (328 oder 2560): du brauchst nämlich dafür einen 16Bit-Timer, und der sollte möglichst nicht für andere Dinge von der Arduino-Library verwendet werden. Der 328 hat nur einen davon, und da stehen die Chancen schlecht, dass er noch frei ist. Das weiß ich aber leider nicht genau. Der ATMega2560 hat dagegen vier 16-Bit-Timer (Timer 1, 3, 4, 5) und da ist ganz sicher noch was frei.

Diesen Counter kanst du dann beispielsweise im Fast PWM-Modus mit 8, 9 oder 10 Bit Auflösung laufen lassen (gibt 256 bis 1024 Schritte) oder mit einer vorgebbaren Anzahl von Schritten (bis 65535).

Informationen dazu finden sich in den Atmel-Datenbüchern zum jeweiligen Controller im Kapitel "16-bit Timer/Counter". Im Übrigen ist zur Erzeugung des PWM-Signals kein Interrupt erforderlich, der Controller macht das alles über Hardware, wenn man ihn vorher entsprechend programmiert. Er zählt dann ganz von allein und erzeugt das PWM-Signal.

Die dafür erforderlichen Schritte sehen in etwa so aus:

  1. Prescaler einstellen (um aus dem Systemtakt einen passenden Timer-Takt zu bekommen)
  2. gewünschten Fast PWM-Modus wählen (8 Bit, 9 Bit, 10 Bit oder 16 Bit variabel (z.B. Mode 15) )
  3. ggfs. max. Zählerstand wählen, bis zu dem gezählt werden soll (wenn nicht 8,9,10 Bit, sondern 16 Bit variabel; z.B. 65535)
  4. festlegen, ob erzeugtes PWM-Signal invertiert oder nicht invertiert sein soll
  5. Zählerwert festlegen, bei dem der Ausgang von low auf high (oder umgekehrt) umgeschaltet wird
  6. Entsprechenden Pin als Ausgang konfigurieren (sonst kommt das PWM-Signal nicht nach außen).
  7. Fertig. Zähler zählt kontinuierlich und erzeugt PWM-Signal.

Das ganze kommt dann in die Funktion setup() und wird einmal aufgerufen. Wenn man das Verhältnis zwischen low und high der PWM ändern will, muss man den Zählerwert (Punkt 5) ändern (in loop()).

Zur Klarstellung: bei 16-Bit PWM heißt es Abschied nehmen von analogWrite(); Datenbuch lesen und Handarbeit in C ist angesagt ;-). Der Aufwand hält sich aber in Grenzen (so 10 bis 15 Zeilen).

Zusammengefasst: das PWM-Signal hängt ab vom Verhältnis des Zähler-Maximalwertes (256, 512, 1024 oder wie selbst gewählt) und dem Zählerwert aus Punkt 5. Die Frequenz, mit der das ganze geschieht, hängt vom Timer-Takt ab, der durch einen Vorteiler aus dem Controllertakt in bestimmten Stufen gewonnen werden kann (Vorteiler von 1 bis 1024 in 10 Stufen) und dem Timer-Maximalwert (aus Punkt 3 bzw. implizit aus Punkt 2).

Gruß Wolfgang

Hallo Wolfgang,

super, danke für die ausführliche Erklärung. Jetzt frag ich mich gerad allerdings woher ich weiss ob der 16Bit Timer schon verwendet wird? Hört sich doch alles ein wenig komplexer an. Wofür könnte ich theoretisch den Timer bereits missbrauchen?

Gruß Thorsten

currymuetze: Jetzt frag ich mich gerad allerdings woher ich weiss ob der 16Bit Timer schon verwendet wird? Hört sich doch alles ein wenig komplexer an. Wofür könnte ich theoretisch den Timer bereits missbrauchen?

Hallo Thorsten, na das ist doch ganz einfach: im Verzeicnis "C:\arduino-0022\hardware\arduino\cores\arduino" einfach alle C-Files ansehen und schon weißt du es.

Nee, war natürlich nur ein Scherz... oder vielleicht doch nicht?

Für millis(), micros(), delay(), usw. scheint nur Timer 0 verwendet zu werden, wenn ich das in wiring.c richtig sehe, dann sollte Timer 1 noch frei sein. Ach ja, tone() verwendet auch noch Timer, abhängig davon, an welchem Pin der Lärm gemacht wird.

Ich hab mir auch mal oberflächlich den Code von analogWrite() und init() angesehen. init() wird ja noch vor setup() aufgerufen. In init() werden zwar auch einige Werte für alle beim jeweiligen Controller vorhandenen Timer gesetzt, aber das kann man ja einfach wieder überschreiben. Und in analogWrite() werden dann die Zählerwerte für die PWM (controllerabhängig) gesetzt.

Ich arbeite zwar auch mit dem Arduino-Board, verwende aber normalerweise nicht die Arduino-IDE und die Arduino-Funktionen, sondern AVR Studio 4 und die AVR GCC-Library. Daher brauche ich mich nicht um das zu kümmern, was andere verborgen hinter meinem Rücken machen, muss aber andererseits Sachen selber machen, die sonst schon für mich gemacht werden.

Daher kann ich dir auch kein fertiges "arduino-taugliches" Programm anbieten, höchstens Unterstützung bei weiteren Fragen.

Wolfgang

Hallo currymuetze

Welche Leistung hat Deine LED Lampe?
Fürs Dimmen von LEDs ist der TLC5940 predestiniert, der kat eine Stromsenke (Konstantstromquelle für LED von +Versorgung zum Ausgang) bis zu 120mA bringen und hat 12bit PWM (4096 Schritte). und braucht einzelne LED oder ein RGB LED mit gemeinsamer Anode.

Viele Grüße Uwe

Hi Uwe,

ich habe 4 LED Stränge mit je 6 3W LEDs an einer 700mA KSQ mit PWM EIngang.

Gru0 Thorsten

Also ein TLC5940 direkt an den Leds geht mal nicht. Du kannst mit den Ausgängen die KSQ ansteuern. Du brauchst an jedem Ausgang einen Pullup Widerstand. 10kOhm müßten gehen ( geschätzt und nicht berechnet) Grüße Uwe

Hi,
d.h.ich schalte den zwischen Arduino und KSQ?
Schau ich mir mal an, 12 BIT wäre ja schon mal ein Fortsschritt

Google frage; der Antwortet auf "arduino tlc5940" an erster Stelle mit: http://www.arduino.cc/playground/Learning/TLC5940. Grüße Uwe

Sagt dir zufällig auch der SITI DM164 was?
Bin in der tat bei google auf der suche gewesen :wink: Dabei auch auf diesen mit immerhin 16BIT PWM gestoßen. ALlerdings möchte ich mich wenn dann eher mit einem IC beschäftigen, der hier im Forum auch bekannt ist und mir geholfen werden kann.

Nettes Teil wenn Du´s auf eine Platine bringst: LQFP48 oder QFN48. Die Programmierung mußt Du dann auch selbst schreiben. Hab keine Ahnung wo Du ihn kaufen kannst. Grüße Uwe

Alles klar, reicht mir schon als Antwort ;) Dann doch mit 12 BIT zufrieden sein, immerhin besser als 8BIT. Werd mir das mal anschauen. Gruß

Eine Frage noch:
Wofür ist der PullUp Widerstand zwischen KSQ und den Ausgängen gut und wie genau berechne ich den?
Anschlussseitig am Arduino kann ich mich an den Infos aus dem Link richten oder?

Gruß

Der Ausgang des TLC zieht einen Konstantstrom auf Masse wenn HIGH. Die KSQ braucht ein PWM signel mit 0 und 5V. Darum braucht es den Widertand. Der Wert ist geschätzt. Der Schaltplan kannst Du 1zu 1 übernehmen; den Widerstand für die Strombegrenzung der Ausgänge kannst Du größer machen 39 oder 47kOhm. Grüße Uwe

Der "normale" Atmega 328 hat auch einen 16 bit Timer. Geht also auch ohne "Umrüsten".

Hallo Udo Ok hat er, aber wieviele 16 Bit PWM Signale kann man damit produzieren? Grüße Uwe

uwefed: Ok hat er, aber wieviele 16 Bit PWM Signale kann man damit produzieren?

Hallo, schaut man ins Datenbuch, sieht man für den 16 Bit-Timer1 die Compare-Register OCR1A und OCR1B und die Pins OC1A und OC1B. Also sieht es ganz nach "2" aus.

Gruß Wolfgang (der sich darüber freut, dass er einen ATMega2560 hat)

=( Für RGB LEDs brauchts aber 3 PWMs. @voithian Du als glücklicher ATMega2560-Besitzer: ein atmega 1280 oder 2560 hat meht 16 bit -Timer. Könnte der das machen? Grüße Uwe