Hallo alle zusammen,
zunächst mal vielen Dank an alle hier, die mir immer antworten und bei meinen Problemen helfen, die eigentlich nie was mit Robotern zu tun haben. Ich vergesse das "gerne", da hier so viele Leute mit hervorragendem Wissen und Erfahrung schreiben.
Ich hoffe auch, ihr habt wieder Lust euch in mein neuestes Problem rein zu denken und Vorschläge zu geben. Wie einige bestimmt mitbekommen haben bin ich zur Zeit am bauen einer RGB-Beleuchtung für mein Wohnzimmer, die ich gerne zunächst via Fernbedienung steuern möchte und später dann eine Kommunikation über IR zwischen PC und mehreren "Licht-Slaves" hinzufügen möchte.
Als Beleuchtung habe ich mir LED-Spots in vier verschiedenen Farben im Halgon-Gehäuse gekauft. Am Wochenende habe ich den ersten Prototypen für die Steuerung auf Lochraster gebaut. Darauf enthalten ist ein Trafo, ein Tiny2313, der IR-Empfänger und 4 PWM-Ausgangsstufen, die wie folgt aussehen:
Die von oben links kommende Leitung ist die gleichgerichtete Versorgungsspannung des 12V-Trafos. (ca. 17V DC). Ich habe bewußt einen stärkeren Treiber (IRF5305) gewählt, um das Ganze eventuell auf richtige Halgon-Spots umbauen zu können, wenn mir die LEDs nicht gefallen.
Hier ist mein Test-Code im Tiny:
Code:
#define AVRGCC
#include <avr/io.h>
#include <util/delay.h>
#include <compiler.h>
#include <avr/interrupt.h>
//F_CPU = 3686400
#define PWM_PreScaler 8
#define PWM_MaxStufen 100
#define PWM_Frequenz 100
#define PWM_OCR (F_CPU / PWM_PreScaler / PWM_MaxStufen / PWM_Frequenz)
#define FarbeRot 0
#define FarbeGruen 1
#define FarbeBlau 2
#define FarbeGelb 3
volatile U8 PWM_level[4] = {0, 0, 0, 0};
volatile U8 PWM_count[4] = {0, 0, 0, 0};
ISR (TIMER0_COMPA_vect)
{
U8 i1;
for (i1 = 0; i1 < 4; i1++)
{
U8 Pin = (1<<i1);
if ((PWM_level[i1] == 0))
PORTB = ~(~PORTB | Pin);
else
{
if (++PWM_count[i1] > PWM_MaxStufen)
PWM_count[i1] = 0;
if (PWM_count[i1] < PWM_level[i1])
PORTB = (PORTB | Pin);
else
PORTB = ~(~PORTB | Pin);
}
}
}
int main (void)
{
DDRB = 0b11111111;
PORTB = 0b00000000;
TCCR0A = (1<<WGM01);
TCCR0B = (1<<CS00);
OCR0A = PWM_OCR;
TIMSK = (1<<OCIE0A);
sei ();
bool DimmUp[4] = {TRUE, TRUE, TRUE, TRUE};
PWM_level[0] = 0;
PWM_level[1] = 30;
PWM_level[2] = 60;
PWM_level[3] = 90;
while (1)
{
U8 i1;
for (i1 = 0; i1 < 4; i1++)
{
if (DimmUp[i1])
{
if (++PWM_level[i1] == PWM_MaxStufen)
DimmUp[i1] = FALSE;
}
else
{
if (--PWM_level[i1] == 5)
DimmUp[i1] = TRUE;
}
}
_delay_us (50);
}
return (0);
}
Die PWM-Ausgabe für die 4 Spots erledige ich "manuell" im Timer0. Ich habe erst mal 100 Helligkeitsstufen mit einer Wiederholfrequenz von 100 Hz gewählt. Im Hauptprogramm werden die 4 Helligkeitswerte in einer Endlosschleife einfach hoch und runter gezählt. Als Ausgansgwert habe ich die 4 Farben mit jeweils 30% Abstand zueinander initialisiert.
Die PWM klappte mit den LEDs auf dem STK500 noch ganz gut, bei den 4 LED-Spots ist das Ergebnis aber nicht gerade berrauschend. Siehe Video:
http://www.car-mp3.de/RNetz/RGB.zip
Das "herunterdimmen" nachdem ich mit der Kamera von den Spots auf die Wand schwenke habe ich der Kamera zu verdanken. Maßgeblich für die Analyse ist das Bild an der Wand, nachdem sich die automatische Helligkeit der Kamera eingeregelt hat.
Meine Meinung: Grün und Blau sind viel zu hell, dass könnte ich aber mit Maximalwerten der einzelen Farben aufeinander abstimmen.
Wozu ich aber noch überhaupt keine Idee habe ist der viel zu geringe Helligkeitsunterschied der einzelnen Farben zwischen 5% Helligkeit und 100%. Wenn ich noch weniger als 5% nehme gehen die Spots quasi aus. 5% ist also das Minimum.
Was meint ihr? Wie bekomme ich die Helligkeitsunterschiede besser hin? Habe ich vielleicht noch einen Fehler im Code, den ich wieder mal vor lauter Bäumen nicht sehe?
Wie findet ihr allgemein den PWM-Code? Kann man da noch was optimieren? Die erste Abfrage in der for-Schleife ( if ((PWM_level[i1] == 0)) ) könnte man weglassen, ich möchte da aber später noch ein globales "Enable-Flag" hinzufügen, dass ich dann in dieser Abfrage mit rein-verodern möchte.
Viele Grüße
Andreas
Lesezeichen