Forum: Mikrocontroller und Digitale Elektronik RGB-Farbsteuerung mit 3 LEDs


von Enrico (Gast)


Lesenswert?

Hallo,

ich habe vor mir eine RGB-Farbsteuerung zu bauen. Diese will ich mit
einem µC von AVR realisieren. Ich hatte mir das vorerst so gedacht,
dass ich ein Potentiometer habe und 3 LEDs. Wenn ich jetzt am Poti
drehe sollen die einzelnen LEDs mittels PWM angesteuert werden, aber
alle mit einer anderen Pulsweite - so dass ich am Ende das gesamte
Farbspecktrum durchlaufen kann (theoretisch!).

Ich habe das ganze bis jetzt nur mit 2 LEDs hinbekommen, leider fällt
mir nichts mehr ein, wie ich da noch eine dritte reinbekommen soll.
Hier ist mal mein bisheriger Code in Bascom:

--------------------------------------------------------
$regfile = "m8def.dat"
$crystal = 3686400
$baud = 9600

On Timer0 Ontimer
On Adc Onadc

Dim Helligkeit As Byte

Ddrd = &B01100000
Ddrc = &B00000000

Tccr0 = &B00000100
Timsk.toie0 = 1

Admux = &B01100000
Adcsr = &B11101111

'--------------------------------

Helligkeit = 255                      'Initial LED ganz hell
Sreg.7 = 1
                                      'Interrupts global einschalten
Do                                    'Hauptschleife
  Helligkeit = Adch                   'Neuer Helligkeitswert
Loop

'--------------------------------

Ontimer:
  Portd.5 = Not Portd.5               'LED wechselnd an/aus
  Portd.6 = Not Portd.6
  If Portd.5 = 1 Then                 'Wenn LED gerade an
    Portd.6 = 0
    Timer0 = 256 - Helligkeit         'Timer zählt vorwärts!
  Else
    Portd.6 = 1                       'Wenn LED gerade aus
    Timer0 = Helligkeit               'Komplementäre Zeit
  End If
Return

Onadc:                                'ADC-Interrupt-Routine
  Udr = Adch
Return
------------------------------------------------------------


Für Hilfe wäre ich sehr dankbar.

Grüße
Enrico

von Dirk (Gast)


Lesenswert?

Hi,

du moechtest also 3 8Bit Software PWM's , weil deine 3 HW PWM's
anscheinend belegt sind.

Ein C Example haette ich ... kenne leider den Syntax von Bascom nicht
mehr so gut.

Bascom (kein getester Code)

Timer0_isroveflow:
z = z +1
if z = 0 then
 reset PORTC.0
 reset PORTD.0
 reset PORTD.1
end if

if z = R then
set PORTC.0
end if

if z = G then
set PORTD.0
end if

if z = B then
set PORTD.1
end if
return

main:
do
R = 20
G = 100
B = 75
loop

Mfg
Dirk

von Enrico (Gast)


Lesenswert?

Hallo,

danke für deine Antwort.
Also da ich noch blutiger Anfänger bin und mich noch nicht so gut
auskenne musst du mir jetzt erst mal verraten was eine HW PWM ist und
wie ich die aktivieren kann?

Dein Code funktioniert zwar, allerdings blinken die LEDs nur im
Sekundentakt und abwechselnd.

Mein Problem besteht ja eigentlich darin, dass ich ein Potentiometer
habe und damit 3 PWMs steuern möchte.

Mal ganz einfach gesagt, würde ich mir das so vorstellen:

Eingangsspannung (Ue) von Poti
Ausgangssignal (PWM) an LEDs

1.
Ue = 0V
PWM1 = 0V
PWM2 = 2V
PWM3 = 4V

2.
Ue = 2V
PWM1 = 2V
PWM2 = 4V
PWM3 = 0V

3.
Ue = 4V
PWM1 = 4V
PWM2 = 0V
PWM3 = 2V

Das ganze müsste linear geregelt sein. Die Werte sind erst einmal frei
gedacht. Mit 3 Potentiometern wäre das ganze ja kein Problem, aber mit
nur einem...

Grüße und danke
Enrico

von Stefan (Gast)


Lesenswert?

Hab ich das so richtig verstanden?

U[out]
^
|.\..LED2../\.LED1
|..\....../..\....
|...\..../....\...
|....\../......\..
|.LED1\/..LED3..\.
--------------------->Ue
.0...33....66...100%

Das heißt, wenn Pe auf 0% ist -> nur LED1
0% <Ue < 33%   -> LED1 + LED2
Ue=33%         -> LED2
33% <Ue < 66%  -> LED2 + LED3
Ue=66%         -> LED3
66% <Ue < 100% -> LED3 + LED1
Ue=100(oder 0 )-> LED1

Sprich es ist immer die selbe hellichkeit aller LED's gegeben?

von Claus Thaler (Gast)


Lesenswert?


von bernd (Gast)


Lesenswert?

Es ist normal, dass µCs nicht unbegrenzt viele PWMs haben. Es ist aber
unter gewissen umständen möglich sich dieses Feature für jeden
beliebigen Port nachzubauen. Einschränkung, die Geschwindingkeit.

Angenommen Du taktest deinen Controller mit 16MHz, dann dauert ein
Befehl ca. 62,5ns. Wenn Du einen Timer so programmierst, dass er alle
100 Zyklen einen TimerIRQ auslöst, ergibt das 6,25µs.
Die möglichen Puls/Pausenweiten können dann ein vielfache von 6,25µs
sein.
Bei 8bit=256Stufen wäre das 6,25µs - 1,6ms(8bit) bzw. 22ms(14bit).
Sollte zur Ansteuerung einer Diode wohl schnell genug sein.

In der TimerIRQ Service Routine einen Counter herunterzählen (für
Output = 1) und bei erreichen von 0, Ausgang toggeln. Dann Counter mit
Ausgangszeitwert für Output = 0 laden und runterzählen. Danach wieder
toggeln und von vorn. Wenn Du den Timer auf alle 1000Zyklen einstellst,
ware es damit sogar möglich alle Ausgange gleichzeitig als "langsame"
SW PWM-output zu nutzen.

Have Fun

von Enrico (Gast)


Lesenswert?

Hallo,

danke für eure Antworten.
Zuerst mal zu Stefan:
wenn ich deine Zeichnung jetzt richtig verstanden habe, dann meine ich
das nicht so. Die PWMs sollen ja gleichzeitig laufen, nicht
nacheinander (so hab ich das jetzt deinem Bild entnommen).
Mein Problem ist jetzt allerding 3 PWMs zu realisieren. Könnte mir da
jemand ein Codebeispiel geben?

@Claus Thaler: genau so etwas in der Art, nur halt mit Potentiometer
und fest einstellbar - also nicht selbstständig wechselnde Farben.

Danke für eure Hilfe.

Grüße
Enrico

von ...HanneS... (Gast)


Lesenswert?

Machs in Assembler, da ist das kinderleicht. War übrigens kürzlich erst
Thema in Verbindung mit einem Tiny15...

von Enrico (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

@HanneS: hast du denn ein passendes Beispiel für Assembler?

Nun noch mal zu den anderen:
Ich habe mir jetzt mal die Mühe gamacht und alle 255 Werte für das
komplatte Farbspecktrum in eine Excel-Liste mit Diagramm zu fassen.
Die Datei findet ihr im Anhang. Also so müsste das im Endeffekt
aussehen, leider bin ich mir nicht im klaren darüber we ich das mit
einem Timer realisieren soll?

Die 3 PWMs habe ich jetzt übrigens hinbekommen. Hier mal mein jetziger
Code:

$regfile = "m8def.dat"
$crystal = 3686400

On Timer0 Ontimer0
Dim Led1 As Byte
Dim Led2 As Byte
Dim Led3 As Byte

Ddrc = &B00000000
Admux = &B01100000
Adcsr = &B11101111

Sreg.7 = 1

Config Pinb.1 = Output
Config Pinb.2 = Output

Tccr0 = &B00000010
Timsk.toie0 = 1

Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B
Pwm = Clear Up , Prescale = 1
Config Timer2 = Pwm , Compare = Clear , Prescale = 1

Do
 Compare1a = Led1
 Compare1b = Led2
 Ocr2 = Led3
Loop

Ontimer0:
  Led1 = Adch
  Led2 = Adch
  Led3 = Not Adch
Return
End

Das funktioniert soweit erst einmal.
Wenn jetzt noch jemand eine Idee hat - immer her damit :-)

Grüße und danke
Enrico

von ...HanneS... (Gast)


Lesenswert?


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
Noch kein Account? Hier anmelden.