endlich ist es soweit, dass ich eine fertige Applikation auf Basis meines Hardware-PWM-Codes aus folgendem Beitrag hier reinstellen kann. Es hat etwas länger gedauert als geplant, aber dafür habe ich einiges an Funktionalität reinpacken können. Die ganze Applikation ist wieder mit BASCOM AVR programmiert und belegt compiliert 5548 Bytes im Flash des MC, weshalb diesmal der ATMEGA48 aussen vor bleibt (nur 4kB Flash).
Das Programm steuert die Farben zweier RGB Quellen unabhängig (6 PWM Kanäle). Es wird diesmal sowohl der Hue-Wert (Farbkreis) als auch die Saturation (Sättigung) gesteuert, so dass nun auch Pastelltöne inkl. Weiss möglich sind. Der Farbkreis ist in 1530 Schritte unterteilt, was effektiv 256 Werte pro RGB-Kanal ergibt, und die Sättigung hat eine Auflösung von 256 Werten. Die PWM-Frequenz beträgt ca. 2 kHz (höher als beim Vorprojekt wegen der erhöhten Werteupdate-Raten). Der PWM-Output kann global über einen Jumper auf invertierend oder nicht-invertierend gesetzt werden (wird bei Programmstart evaluiert), je nachdem wie man die LEDs anschliesst (direkt oder über Transistor, FET, Treiber etc.). Wenn bei Ausgang = 5V (1) die LED leuchtet, dann ist nicht-invertierend zu wählen, ansonsten wenn bei Ausgang = Masse (0) die LED leuchtet, dann ist invertierend zu wählen.
Über 5 Tasten wird der MC gesteuert. Mit der Prog.-Taste kann eines der 15 Programme (zyklisch) ausgewählt werden. Die Speed-Taste steuert die Geschwindigkeit in 8 Schritten (ca. 3 sek. bis ca. 6.5 min. für einen Rainbow-Durchlauf; jeweils verdoppelung von Schritt zu Schritt) zyklisch. Mit der Brightness-Taste wird global die Helligkeit in vier Schritten (100%, 50%, 25% und Aus) zyklisch eingestellt. Mit der Stop/Start-Taste für die jeweilige RGB-LED kann die Sequenz angehalten und wieder laufen gelassen werden.
Die Programmwechsel und Speed-Einstellungen wirken sich jeweils nur auf die RGB-LED aus, bei welcher die Sequenz läuft. So kann man Programm und Speed unabhängig für jede RGB-LED einstellen. Wenn beide Sequenzen laufen, so wirken sich Programmwechsel und Speedwechsel simultan auf beide RGB-LEDs aus (zum schnellen durchzappen).
Sind beide Sequenzen gestoppt, haben Programm- und Speed-Taste alternative Funktionen. Mit der Speed-Taste können in diesem Fall die aktuellen Werte für Programm und Speed beider RGB-LEDs sowie die globale Helligkeit im internen EEPROM (nichtflüchtiger Speicher) gespeichert werden. Als visuelle Bestätigung des Speichervorgangs gehen beide LEDs aus und flashen dann kurz einmal grün auf, bevor sie wieder in den ursprünglichen Zustand versetzt werden. Die Programm-Taste hat genau die entgegengesetzte Sekundärfunktion (wenn beide Sequenzen gestoppt sind). Sie liest dann die gespeicherten Werte aus dem EEPROM aus und versetzt die beiden RGB-LEDs in die entsprechenden Zustände (Programm, Speed, Helligkeit global). Die entsprechenden Programme starten dann von Anfang.
Beim Programmstart wird auch das EEPROM gelesen. D.h. dass beim Einschalten jeweils die zuletzt gespeicherten Einstellungen verwendet werden, ausser es ist noch nichts gespeichert (beim ersten Einschalten z.Bsp.), dann initialisieren sich beide RGB-LEDs mit Program 0, schnellster Geschwindigkeit und höchster globaler Helligkeit.
Zu den Programmen:
Erklärung zur Sättigung: 0% ergibt einfach weiss, unabhängig vom Hue-Wert (Farbkreis). Wenn man die Sättigung verringert ergibt sich also ein Effekt wie wenn man noch mit einer weissen LED überblenden würde.
0: Regenbogen vorwärts
1: Regenbogen vorwärts bei 75% Sättigung
2: Regenbogen vorwärts bei 50% Sättigung
3: Regenbogen vorwärts bei 25% Sättigung
4: Regenbogen rückwärts
5. Regenbogen alternierend (vorwärts <-> rückwärts)
6: Springen durch die 7 Grundfarben (rot, gelb, grün, cyan, blau, magenta und weiss)
7: Regenbogen vorwärts und bei jedem zweiten Durchgang gleichzeitig Überblenden zu Weiss und zurück
8: Regenbogen vorwärts und gleichzeitig sehr langsam (in 40 Regenbogen-Durchgängen) Überblenden zu Weiss und zurück
9: Rot <-> Grün gleitend
10: Grün <-> Blau gleitend
11: Blau <-> Rot gleitend
12: Springen durch zufällige Werte von Hue und Sättigung
13: Regenbogen vorwärts und gleichzeitig Springen durch zufällige Werte von Sättigung
14: Gleiten von Weiss zu einem zufälligen Hue-Wert und zurück (immer wieder)
Natürlich kannt man je nach Geschmack diese Programme verändern, weglassen und abhängig vom zur Verfügung stehenden Flash-Speicher weitere hinzufügen. Alle Programme sind in der Funktion Prog_call als If-Then-Blöcke programmiert. Wichtig dabei ist, dass die Länge eines Programmdurchlaufes maximal 65535 Schritte bzw. Zeiteinheiten (Zeiteinheit: min. ca. 2 ms, max. ca. 256 ms je nach Speed) beträgt. Man markiert das Ende eines Programmdurchlaufes mit dem Setzen der Variable Prog_call auf 1 (siehe Programme). Die Schrittzahl entnimmt man der Variable Curr_step und programmiert aufgrund dieser Zahl den Ablauf in Farbkreis-Wert (Hue_val, 0 - 1529) und Sättigung (Sat, 0 - 255). Die Variable Prog beinhaltet das aktuell eingestellte Programm, was man für die If-Then-Weichen nutzen kann (siehe Programme). Wichtig ist auch noch, dass man die Konstante Maxprog auf die höchste Programmnummer (Anzahl Programme - 1, da die Programme mit Nummer 0 beginnen) setzt.
Manch ein Programmierguru wird vielleicht anmerken: Weshalb ist denn der Programmierstil so unelegant ?
Ich hatte leider keine Zeit, noch Videos oder Bildeindrücke anzufertigen, aber ich habe den programmierten Chip in einem Testaufbau ausgiebig getestet. Der Code funktioniert fehlerlos. Die Farbverläufe sind butterweich (noch besser als beim Vorprojekt; grössere Hue-Auflösung: 1530 gegenüber 252, höhere Werteupdaterate und höhere PWM-Frequenz: 2 kHz gegenüber 245 Hz) und es ist zumindest bei den von mir für den Test verwendeten RGB-LEDs (Superflux) kein Anflug von Flackern festzustellen. Sobald ich mit dem Chip eine kleine Design-Mood-Leuchte zusammengebastelt habe, folgt natürlich ein weiteres HowTo, dann mit Bildern und Videos.
Noch ein kleiner Hinweis für alle, die per Darlington oder MOSFET High-Power-LEDs oder ganze LED-Gruppen steuern möchten: Bei einer PWM-Frequenz von ca. 2 kHz sind bei den extremen PWM-Werten (wie 1 und 254) die Pulse teilweise nur noch ca. 2 us (mikrosekunden) breit. Man sollte also darauf achten, dass man Transistoren verwendet, welche schnell genug schalten können (mindestens ca. 1MHz Bandbreite). Bei MOSFETs ist die Bandbreite meist nicht limitierend, aber da ergibt sich leider ein anderes Problem. Der Gate-Steuereingang eines MOSFET weist eine teilweise nicht unerhebliche Kapazität auf, welche bei solch kurzen Schaltzeiten zu kurzzeitig recht hohen Umladungsströmen am Gate-Eingang resp. am MC-Ausgang führen kann. Diese sollte man mit einem Widerstand zwischen MC-Ausgang und Gate-Eingang limitieren. 100 Ohm sollten bei einem AVR reichen. Dies begrenzt den Schaltstrom auf ca. 50 mA (ein AVR sollte bei solch kurzen Schaltzeiten bis 100 mA locker verkraften). Nun bildet aber der Begrenzungswiderstand mit der Gate-Kapazität ein RC-Glied (Lowpass-Filter in diesem Fall), welches die maximale Schaltfrequenz stark limitieren kann. Man sollte also bei der Auswahl des MOSFETs auf eine möglichst niedrige Gate-Kapazität achten. Ich selbst verwende für die meisten High-Power-LED-Anwendungen den IRLD110, welcher bis zu 1A bei 0.5 Ohm ON-Widerstand schalten kann bei 'nur' 250pF Gate-Kapazität. Dies führt bei 100 Ohm laut "R * C * 2 * Pi" noch zu keinerlei Problemen. Ausserdem ist er Logic-Level (schaltet ab ca. 3V voll durch) und wird im äusserst praktischen HEXDIP-Gehäuse angeboten. MOSFETs für sehr hohe Ströme mit extrem niedrigen ON-Widerständen haben nicht selten Gate-Kapazitäten von mehreren nF, was dann doch schon problematisch wird. Wenn man auf solche Schaltaufgaben nicht verzichten kann, dann sollte man einen MOSFET-Treiber (meist kleine Treiber-ICs) vor den POWER-MOSFET schalten.
Ok, nun genug der Erklärungen und der Theorie: Nachfolgend sind der Code und der Schaltplan meiner Testschaltung (kann man als Basis-Applikationsschaltung ansehen) angegeben. Ich wünsche allen, die sich dranwagen viel Erfolg
Gruss
Neni





