Beistellleuchte mit ATMega8A-Steuerung

Anleitungen für "hausgemachte" LED Projekte

Moderator: T.Hoffmann

Antworten
ustoni
Auserwählter
Auserwählter
Beiträge: 2105
Registriert: Sa, 04.06.11, 12:39
Wohnort: Mechernich

Mi, 01.03.17, 09:24

Bei der hier beschriebenen Beistellleuchte habe ich bei der Helligkeitssteuerung mal einen etwas anderen Weg beschritten. Als Leuchtmittel dienen 2 LumiFlexPerformer LED Leisten mit je 70 LEDs (http://www.leds.de/LED-Leisten-Module/F ... weiss.html). Diese habe ich in 20 Segmente zerteilt und in 10 2er-Gruppen auf ein 3 cm breites Alu-Flachprofil aus eloxiertem Aluminium aufgeklebt. Jede 2er-Gruppe lässt sich einzeln ansteuern. Abgedeckt wurden die Leisten mit einer diffusen Kunststoffabdeckung (http://www.leds.de/LED-Zubehoer/Alumini ... iffus.html). Als Stromversorgung dient ein Meanwell RS-25-24.
01 Lampe komplett.jpg
Bei diesem Projekt ging es mir hauptsächlich um die Ansteuerung der Segmente mit einem ATMega8A und der in der Programmiersprache BASCOM erstellten Software. Vor gut eineinhalb Jahren hatte ich mir das myAVR BASCOM-Komplettpaket MK2 PLUS gekauft. (http://shop.myavr.de/Komplettpakete/myA ... tID=200053)
Seitdem schlummerte das Paket - nach intensiver Sichtung, aber ohne passende Anwendung - in einem Schrank. Jetzt sollte endlich das erste Programm geschrieben werden.

Die Helligkeitsteuerung erfolgt in diesem Fall durch Zu- und Abschalten einzelner LED-Segmente auf Tastendruck. Folglich sind 10 Helligkeitsstufen zwischen ca. 200 lm und 2000 lm (Verluste durch die diffuse Abdeckung berücksichtigt) möglich. Hier mal nebeneinander von links nach rechts die Leuchte mit einer, 3, 5, 7 und 10 eingeschalteten Segmenten:
02 L1bis10.jpg
In Wirklichkeit überstrahlen die LEDs natürlich nicht so wie auf dem Foto dargestellt. Das liegt einfach an der Programmautomatik der Kamera. Trotzdem sind 2000 lm auf knapp 60 cm Länge und 3 cm Breite schon brutal hell. Im Nachhinein betrachtet hätte ein LED-Streifen auch gereicht.

Da die Ansteuerung ohnehin über einen ATMega erfolgt, kann man natürlich auch leicht ein paar Effekte programmieren. Also habe ich noch 5 Effekte programmiert, die sich ebenfalls per Tastendruck aufrufen lassen:
1. Schneefall 1: Segmente werden von oben nach unten durchgeschaltet, wobei immer nur ein Segment leuchtet.
2. Schneefall2: wie oben, es leuchten aber immer 2 Segmente, weitergeschaltet wird immer um ein Segment.
3. Wischer: beginnt mit dem obersten und untersten Segment, beide Segmente laufen aufeinander zu und dann wieder voneinander weg.
4. Nightrider: das oberste Segment läuft nach unten und anschließend zurück nach oben.
5. Blitzer: alle 10 Segmente leuchten ca. 3 mal je Sekunde für 10 Millisekunden auf.

Auf Fotos lassen sich die Effekte leider nicht darstellen. Die Dauer für einen Durchlauf beträgt bei den ersten drei Effekten ca. 1 Sekunde, bei Effekt 4 ca. 1,8 Sekunden.

Zunächst musste eine entsprechende Steuerplatine her. Ursprünglich wollte ich die nötige Schaltung auf einer Lochrasterplatine aufbauen. Aufgrund der relativ vielen Bauteile hätte das aber nicht mehr schön ausgesehen. Also habe ich beschlossen, entsprechende Platinen bei MME (http://www.mme-pcb.com/) fertigen zu lassen.

Da dies keine ganz billige Angelegenheit ist, habe ich eine Platine entworfen, die sich bei maximal 16 Kanälen universell verwenden lässt. Dabei ist folgende Schaltung (erstellt mit DesignSpark PCB) herausgekommen:
03 Schaltplan (1).jpg
Dabei zu beachten: es werden niemals alle Bauteile bestückt. Die 5V-Versorgung kann wahlweise durch einen 7805 oder einen LM317 erfolgen. Quarz und zugehörige Kondensatoren werden nur benötigt, wenn der ATMega 8A mit externem Takt laufen soll. Nicht benötigte Stiftleisten werden nicht bestückt.

Die Ports B und D des ATMega steuern je Pin einen Transistorschaltstufe an. Die Dioden sind sicherheitshalber erforderlich, da der LOW-Pegel des ATMega je nach Typ bis zu 0,8 bzw. 0,9V betragen kann.
Die ungewöhnlichen Schaltzeichen für die Schalttransistoren ergeben sich daraus, dass hier je nach Anwendung unterschiedliche Transistoren verwendet werden können. Vorgesehen sind BC548 (Kleinleistung), BC140 (max. 1 A) sowie IRLU024N (max 12 A, auf ca. 5 A begrenzt durch Leiterbahnbreite).

Das passende Platinenlayout ist ebenfalls mit DesignSpark PCB erstellt. Abmessungen der Platine: 10 cm x 10 cm. Falls jemand Bedarf für die DesignSpark-Dateien hat, einfach eine PN an mich schicken.
Lötseite:
04 Layout Bottom.jpg
Bestückungsseite:
05 Layout Top.jpg
Da in der Mitte rechts noch Platz war, habe ich dort ein Lochrasterfeld integriert. Bei MME habe ich dann 2 Platinen fertigen lassen:
06 Platine.jpg
Zwischen obigen Layouts und den abgebildeten Platinen sind noch leichte Unterschiede in der Leiterbahnführung zu erkennen. Das liegt daran, dass ich die Layouts später noch etwas optimiert habe. Außerdem fehlt (leider) auf der Platine noch eine Leiterbahn (Masseleitung 2. Transistor von unten, linke Seite), das ließ sich beim Bestücken aber leicht korrigieren. Dieser Fehler ist in den aktuellen Layouts natürlich behoben.

Die unterschiedliche Bestückung mit Transistoren würde so aussehen:
08 Transistoren.jpg
Für die hier beschriebene Leuchte werden nur 10 Kanäle gebraucht. Dadurch reduziert sich der Schaltplan wie folgt:
09 Schaltplan .jpg
Als Transistoren habe ich BC140 verwendet. (Davon hatte ich noch ausreichend hier)

Die entsprechend bestückte Platine:
10 Platine bestückt.jpg
Oben links zu sehen: die "Reparatur" der fehlenden Leiterbahn.
Verdrahtungsplan der Leuchte:
11 Verdrahtung.jpg
Schalter S1 ist ein 2-poliger Netzschalter, Taster S2 bis S4 dienen der Lichtsteuerung. Dabei wird mit den Tastern S2 und S3 in der normalen Betriebsart als Leuchte heller und dunkler gesteuert. Bei kleinster Helligkeitsstufe ist nur das oberste Segment an. Mit S3 wird mit jedem Tastendruck um eine Stufe heller geschaltet. Bei der Abfrage von S2 und S3 ist ein Überlauf programmiert. Sind z.B. alle 10 Segmente an und wird S3 erneut gedrückt, ist nur noch das oberste Segment an.

Taster S4 schaltet von der normalen Betriebsart in den Effektmodus um. Im Effektmodus schaltet S4 dann zwischen den verschiedenen Effekten um. Der Effektmodus wird durch Drücken von Taster S2 oder S3 beendet.

Der Buzzer ist ein kleiner Piezobuzzer mit 5V/20mA. Da habe ich mir - entgegen meiner sonstigen Gewohnheit - einen 10er-Pack über ebay aus China bestellt. Per Software wird bei jedem Tastendruck als Quittierung ein kurzer Piepston erzeugt.

Taster und Buzzer habe ich zur einfacheren Befestigung im Gehäuse auf einen Streifen Lochrasterplatine gelötet.

Die eigentliche Konstruktion der Leuchte gestaltet sich recht einfach. Der Sockel besteht aus einem Alublech 20 cm x 20 cm x 2 mm und 4 Aluwinkeln 4 cm x 1 cm x 20 cm. Die 1 cm breite Seite und die 4 cm hohen Kanten habe ich grob auf Gehrung gesägt und gefeilt und - nach Anbringen der Löcher für Schalter und Taster im Alublech - mit UHU Endfest 300 auf das Alublech geklebt. Das hält nach Aushärten des Klebers bombenfest:
12 Sockel Bottom.jpg
In die Rückseite des Sockels wurden dann noch 4 Löcher zum Befestigen des Aluprofils sowie ein Loch für die Kabeldurchführung des Netzteils gebohrt. Mittig an der oberen Hinterkante der Oberseite ist noch ein weiteres Loch als Kabeldurchführung für die Leitungen zu den LEDs erforderlich. Außen wird der Sockel dann grundiert und lackiert:
13 Sockel top.jpg
In die 4 Ecken des Sockels habe ich noch 4 M3-Muttern geklebt (ebenfalls mit UHU endfest 300). Diese dienen später zum Festschrauben der Bodenplatte. Die Bodenplatte habe ich aus einem Stück FR4 Platinenmaterial passend zurechtgesägt.

Den Sockel hätte ich auch etwas kleiner machen können, ich habe aber einfach Material verwendet, das ich noch hier hatte.

Das Alu-Flachprofil wird auf eine Länge von 64 cm gebracht und mit vier Bohrungen zur Befestigung am Sockel versehen. Dann werden die Segmente des LED-Streifens aufgeklebt:
14 LEDs.jpg
Die Anodenanschlüsse sowie die jeweils benachbarten Kathodenanschlüsse habe ich mit kurzen Drahtstücken miteinander verlötet. Hierfür eignen sich hervorragend die Drahtreste, die beim Bestücken der Platine mit den Widerständen anfallen.
15 LEDs Verbindungen.jpg
Anschließend werden die Segmente sowie der gemeinsame Anodenanschluss mit Kabeln (AWG24 = 0,205 mm²) versehen. Die Kabel habe ich mit normalem Zwirn zu einem Kabelbaum gebunden:
16 LEDs Kabelbaum.jpg
Das Kabel wird dann durch das Loch an der Oberseite des Sockels geführt und das Flachprofil mit dem Sockel verschraubt. Der Rest ist Fleißarbeit.
Verdrahtung der 230-V-Seite:
17 Verdrahtung 230.jpg
Und die Unterseite komplett verdrahtet:
18 Sockel verdrahtet.jpg
Wie man sieht, habe ich den 230 V-Bereich komplett mit Heißkleber vergossen. Muss man natürlich nicht.

Auf den Spannungsregler habe ich noch einen IC-Kühlkörper geklebt. Ohne Kühlkörper wird der Regler zu heiß. Die Schaltung benötigt zwar nur ein paar Milliampere, die 5 V werden aber direkt aus den 24 V des Netzteils gewonnen.

An die beiden Platinen habe ich vor dem Verdrahten je 4 M3x30-Schrauben mit 2 Muttern je Schraube angebracht. Mit dem Muttern habe ich den jeweils erforderlichen Abstand eingestellt und die Platinen dann im Gehäuse fixiert, indem ich auf jeden Schraubenkopf einen Tropfen UHU endfest 300 aufgetragen habe und die Platinen dann passend positioniert habe. Auch das hält nach dem Aushärten bombenfest.

Nach dem erfolgreichen Funktionstest habe ich noch die diffuse Abdeckung aufgeklebt (wie kann es anders sein - mit UHU endfest 300).

Wie eingangs erwähnt liegt der Lichtstrom bei 200 bis 2000 Lumen, einstellbar in Schritten von 200 Lumen. Bei niedrigster Helligkeitsstufe beträgt die Leistungsaufnahme 3 W, bei höchster Helligkeitsstufe 24 W. Das Aluflachprofil erreicht (ebenfalls bei höchster Stufe) bei 25°C Umgebungstemperatur maximal 56°C.

Abschließend noch das Programmlisting. Das Programm ist ausführlich mit Kommentarzeilen versehen und damit praktisch selbsterklärend. Zur besseren Lesbarkeit sind die eigentlichen Programmzeilen in blauer Schrift dargestellt. Das fertig kompilierte Programm hat eine Dateigröße von knapp 2 kB.

--------------------------------------------------------------------------------------------------------------------------------------------------------------------
' Programm: Lichtbandsteuerung
' Funktion: 10-Step-Dimmung + Effektprogramme
' Controller: Mega8A
'--------------------------------------------------
' $regfile teilt dem BASCOM-Compiler mit, welcher Prozessor verwendet wird
' $crystal teilt dem Compiler mit, mit welcher Taktfrequenz der Prozessor arbeitet
$regfile = "M8adef.dat" ' Mikrokontroller
$crystal = 1000000 ' Taktfrequenz
' Hardware- und Softwarestack:
$hwstack = 48
$swstack = 32
$framesize = 60

'
' Ports konfigurieren:
' --------------------
' Wird kein spezifischer Pin angegeben, werden alle Leitungen
' des Ports gleichartig konfiguriert. Bei Angabe eines Pins
' (z.B. .0) wird nur dieser einzelne Pin konfiguriert.
Config Portb = Output ' LED9, 10
Config Portd = Output ' LED1-8
Config Portc.0 = Input ' Taste UP
Config Portc.1 = Input ' Taste DOWN
Config Portc.2 = Input ' Taste EFFEKT
Config Portc.3 = Output ' Buzzer
'
' Pull-Up-Widerstände für Taster schalten:
' ----------------------------------------
' Mit PORTx.y=1 wird ein als Output definierter Port auf High gesetzt.
' Ist dieser Port als Input konfiguriert, wird mit der gleichen
' Befehlszeile der interne Pull-Up-Widerstand zwischen den Pin und
' VCC geschaltet. Sind die Taster nicht gedrückt, wird so ein
' definiertes HIGH erzeugt.
Portc.0 = 1
Portc.1 = 1
Portc.2 = 1

'
' Namen für Ports vergeben:
' -------------------------
' Mit dem Befehl Alias wird dem rechts vom Befehl stehenden Port oder Pin
' der links stehende Name zugeordnet. Dies erleichtert sowohl die
' Programmierung als auch die Lesbarkeit des Programms.
Led1 Alias Portd
Led2 Alias Portb
Up Alias Pinc.0
Down Alias Pinc.1
Effekt Alias Pinc.2
Buzzer Alias Portc.3

'
' Variablen deklarieren:
' ----------------------
' Zählervariable für Helligkeit im Standardbetrieb
Dim Count As Byte
' Zählervariable für Effekte
Dim Effcount As Byte
' Statusvariable für Effektbetrieb, 0=Standard, 1=Effekt
Dim Eff As Byte
' Statusvariable für Art des Effekts
' 1 = Lauflicht
' 2 = Doppel-Lauflicht
' 3 = Wischer
' 4 = Nightrider
' 5 = Stroboskop
Dim Effektnr As Byte
' Arrays für Standardbetrieb
Dim L1(10) As Byte ' für LED 1 - 8
Dim L2(10) As Byte ' für LED 9 und 10
' Arrays für Effektbetrieb
Dim E11(10) As Byte
Dim E12(10) As Byte
Dim E21(10) As Byte
Dim E22(10) As Byte
Dim E31(10) As Byte
Dim E32(10) As Byte
Dim E41(18) As Byte
Dim E42(18) As Byte

'
' Variablen initialisieren
' ------------------------
' Hinweis: bei Programmstart werden alle deklarierten Variablen auf den Wert
' Null gesetzt. Dieser Wert muss deshalb nicht explizit vergeben werden.
'
' Anfangshelligkeit = 50%:
Count = 5
'
' Effektart Lauflicht als Startwert:
'
Effektnr = 1
' Array für Helligkeit (binär, weil besser lesbar):
L1(1) = &B00000001
L1(2) = &B00000011
L1(3) = &B00000111
L1(4) = &B00001111
L1(5) = &B00011111
L1(6) = &B00111111
L1(7) = &B01111111
L1(8) = &B11111111
L1(9) = &B11111111
L1(10) = &B11111111

'
L2(9) = &B00000001
L2(10) = &B00000011

'
' Array für Effekt1 (Lauflicht):
E11(1) = &B00000001
E11(2) = &B00000010
E11(3) = &B00000100
E11(4) = &B00001000
E11(5) = &B00010000
E11(6) = &B00100000
E11(7) = &B01000000
E11(8) = &B10000000
E11(9) = &B00000000
E11(10) = &B00000000

'
E12(9) = &B00000001
E12(10) = &B00000010

'
' Array für Effekt2 (Doppel-Lauflicht):
E21(1) = &B00000011
E21(2) = &B00000110
E21(3) = &B00001100
E21(4) = &B00011000
E21(5) = &B00110000
E21(6) = &B01100000
E21(7) = &B11000000
E21(8) = &B10000000
E21(9) = &B00000000
E21(10) = &B00000000

'
E22(8) = &B00000001
E22(9) = &B00000011
E22(10) = &B0000010

'
' Array für Effekt3 (Wischer):
E31(1) = &B00000001
E31(2) = &B00000010
E31(3) = &B10000100
E31(4) = &B01001000
E31(5) = &B00110000
E31(6) = &B00110000
E31(7) = &B01001000
E31(8) = &B10000100
E31(9) = &B00000010
E31(10) = &B00000001

'
E32(1) = &B00000010
E32(2) = &B00000001
E32(9) = &B00000001
E32(10) = &B00000010

'
' Array für Effekt4 (Nightrider):
E41(1) = &B00000001
E41(2) = &B00000010
E41(3) = &B00000100
E41(4) = &B00001000
E41(5) = &B00010000
E41(6) = &B00100000
E41(7) = &B01000000
E41(8) = &B10000000
E41(9) = &B00000000
E41(10) = &B00000000
E41(11) = &B00000000
E41(12) = &B10000000
E41(13) = &B01000000
E41(14) = &B00100000
E41(15) = &B00010000
E41(16) = &B00001000
E41(17) = &B00000100
E41(18) = &B00000010

'
E42(9) = &B00000001
E42(10) = &B00000010
E42(11) = &B00000001

'
' Endlosschleife innerhalb DO - LOOP
' ----------------------------------
' Hier werden für Standardbetrieb die Tasten abgefragt und die LEDs
' geschaltet. Auswertung der Tasten und Effekte laufen in
' eigenen Subroutines (Unterprogramme).
Do
'
' LEDs abhängig von der Variablen Count schalten:
Led1 = L1(Count)
Led2 = L2(Count)

'
' Tasten abfragen:
' ----------------
' Zum Abfragen der Tasten wird der Befehl DEBOUNCE verwendet.
' Syntax:
' Debounce, Portpin, Wert (0/1), Subroutine, Sub
' Der Portpin ist der abzufragende Pin.
' Wert ist der erwartete Wert bei gedrückter Taste. Ist die Taste z.B.
' gegen Masse (GND) geschaltet, ist der erwartete Wert bei gedrückter
' Taste 0.
' Subroutine ist der Name des Unterprogramms, das bei gedrückter Taste
' ausgeführt wird. Sub schließt den Befehl ab.
' Der Debpunce-Befehl führt eine automatische Tastenentprellung durch.
' Wurde z.B. als Wert 0 angegeben, wird bei einer 1 sofort die folgende
' Programmzeile ausgeführt. Wird aber bei Ausführung des Befehls eine 0
' detektiert, wartet der Befehl 25 ms (diese Zeit ist mit Config Debounce
' änderbar, 25 ms ist Default) und überprüft den Pin dann erneut. Nur
' wenn jetzt immer noch eine 0 anliegt, wird das Unterprogramm ausgeführt.
' So wird der Tastendruck entprellt. Der Befehl wird erst dann erneut
' ausgeführt, wenn nach den 25 ms eine 1 detektiert wurde. Dadurch wird
' verhindert, dass der Befehl bei gedrückt gehaltener Taste ungewollt
' mehrfach ausgeführt wird.
'
Debounce Up , 0 , Oben , Sub
Debounce , Down , 0 , Unten , Sub
Debounce , Effekt , 0 , Effekttaste , Sub

'
' Zum Effektmodus springen, wenn Statusvariable Eff=1:
'
If Eff = 1 Then
Gosub Effektmodus
End If

'
' Schleife schließen:
'
Loop
'
' Unterprogramme:
' ---------------
'
' Subroutine Oben wird bei Drücken der Taste Up angesprungen.
' -----------------------------------------------------------
'
Oben:
'
' Variable Count um 1 verkleinern:
'
Decr Count
'
' Überlauf, wenn Count = 0:
'
If Count = 0 Then
Count = 10
End If

'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0

'
Return
'
' Subroutine Unten wird bei Drücken der Taste Down angesprungen.
' --------------------------------------------------------------
'
Unten:
'
' Variable Count um 1 vergrößern:
'
Incr Count
'
' Überlauf, wenn Count = 11
'
If Count = 11 Then
Count = 1
End If

'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0

'
Return
'
' Subroutine Effekttaste wird bei Drücken der Taste Effekt angesprungen.
' ----------------------------------------------------------------------
'
Effekttaste:
'
' Statusvariable Eff auf 1 setzen:
'
Eff = 1
'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0

'
Return
'
' -----------------------
' Subroutines für Effekte
' -----------------------
'
' Subroutine Effektmodus erzeugt die Effekte abhängig von Variablen
'------------------------------------------------------------------
'
Effektmodus:
'
' Zählervariable auf 1 setzen
' Wird der Effektmodus gewählt, beginnt der Effekt dadurch immer am Anfang
'
Effcount = 1
'
' Der Effektmodus läuft in einer While-Schleife.
' Die Schleife wird automatisch verlassen, wenn die Variable Eff
' auf 0 gesetzt wird
'
while Eff = 1
'
' Effekt 1 durchführen wenn zutreffend
'
If Effektnr = 1 Then
'
' LEDs setzen und warten:
'
Led1 = E11(Effcount)
Led2 = E12(Effcount)
Waitms 100

'
' Tasten abfragen:
' Tasten Up oder Down beenden den Effektmodus, Taste Effekt
' springt zum nächsten Effekt
'
Debounce Up , 0 , Effektende , Sub
Debounce , Down , 0 , Effektende , Sub
Debounce , Effekt , 0 , Effektplus , Sub
End If

'
' Effekt 2 durchführen wenn zutreffend
'
If Effektnr = 2 Then
'
' LEDs setzen und warten:
'
Led1 = E21(Effcount)
Led2 = E22(Effcount)
Waitms 100

'
' Tasten abfragen:
' Tasten Up oder Down beenden den Effektmodus, Taste Effekt
' springt zum nächsten Effekt
'
Debounce Up , 0 , Effektende , Sub
Debounce , Down , 0 , Effektende , Sub
Debounce , Effekt , 0 , Effektplus , Sub
End If


'
' Effekt 3 durchführen wenn zutreffend
'
If Effektnr = 3 Then
'
' LEDs setzen und warten:
'
Led1 = E31(Effcount)
Led2 = E32(Effcount)
Waitms 100

'
' Tasten abfragen:
' Tasten Up oder Down beenden den Effektmodus, Taste Effekt
' springt zum nächsten Effekt
'
Debounce Up , 0 , Effektende , Sub
Debounce , Down , 0 , Effektende , Sub
Debounce , Effekt , 0 , Effektplus , Sub
End If

'
' Effekt 4 durchführen wenn zutreffend
'
If Effektnr = 4 Then
'
' LEDs setzen und warten:
'
Led1 = E41(Effcount)
Led2 = E42(Effcount)
Waitms 100

'
' Tasten abfragen:
' Tasten Up oder Down beenden den Effektmodus, Taste Effekt
' springt zum nächsten Effekt
'
Debounce Up , 0 , Effektende , Sub
Debounce , Down , 0 , Effektende , Sub
Debounce , Effekt , 0 , Effektplus , Sub
End If

'
' Effekt 5 durchführen wenn zutreffend
'
If Effektnr = 5 Then
'
' LEDs setzen und warten:
'
Led1 = &B11111111
Led2 = &B00000011
Waitms 10
Led1 = &B00000000
Led2 = &B00000000
Waitms 300

'
' Tasten abfragen:
' Tasten Up oder Down beenden den Effektmodus, Taste Effekt
' springt zum nächsten Effekt
'
Debounce Up , 0 , Effektende , Sub
Debounce , Down , 0 , Effektende , Sub
Debounce , Effekt , 0 , Effektplus , Sub
End If

'
' Zählervariable um 1 erhöhen und auf 1 setzen wenn Überlauf abhängig vom Effekt:
'
Incr Effcount
If Effcount = 11 AND Effektnr < 4 then
Effcount = 1
Elseif Effcount = 19 AND Effektnr = 4 then
Effcount = 1
Elseif Effektnr = 5 then
Effcount = 1
End If

'
' While-Schleife abschließen:
'
Wend
'
' Effektmodus beenden:
'
Return
'
' Subroutine Effektende setzt Variable Eff auf 0 und beendet
' dadurch den Effektmodus
:
Effektende:
Eff = 0

'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0
Return

'
' Subroutine Effektplus inkrementiert die Variable Effektnr und
' wählt dadurch den nächsten Effekt. Überschreitet der Wert den
' maximal zulässigen Wert, wird die Variable auf 1 gesetzt
'
Effektplus:
Incr Effektnr
If Effektnr = 6 Then
Effektnr = 1
End If

'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0
Return

'
' Programmende:
'
End
Zuletzt geändert von ustoni am Mi, 01.03.17, 10:35, insgesamt 1-mal geändert.
Borax
Star-Admin
Star-Admin
Beiträge: 11980
Registriert: Mo, 10.09.07, 16:28

Mi, 01.03.17, 10:30

Schön geworden!
Der Link zur diffusen Kunststoffabdeckung ist falsch. Der zeigt auf die Leisten.
Die Dioden sind sicherheitshalber erforderlich, da der LOW-Pegel des ATMega je nach Typ bis zu 0,8 bzw. 0,9V betragen kann.
Das ist IMHO nicht nötig. Die 0.9V max. Output voltage bei Low Pegel gelten nur bei 'Extrembedingungen'. Also hohe Temperatur, niedrige Versorgungsspannung und hoher Strom. Keine dieser Bedingungen ist bei Deiner Anwendung gegeben. Bei 5V Versorgungsspannung beträgt die max. Spannung nur 0.55V selbst wenn 20mA Strom 'vernichtet' werden müssen und die Temperatur bei 85°C liegt:
Atmega8A_LowVoltage5V.png
Atmega8A_LowVoltage5V.png (21.75 KiB) 6181 mal betrachtet
Nur bei 3V Versorgungsspannung und mehr als 15mA Sink-Strom könnte der Low Pegel über 0.6V liegen:
Atmega8A_LowVoltage3V.png
Atmega8A_LowVoltage3V.png (22.01 KiB) 6181 mal betrachtet
ustoni
Auserwählter
Auserwählter
Beiträge: 2105
Registriert: Sa, 04.06.11, 12:39
Wohnort: Mechernich

Mi, 01.03.17, 10:40

Danke für den Hinweis! Hab den Link korrigiert.

Mit den Dioden hast Du sicherlich recht. Ich hab sie halt sicherheitshalber eingebaut. So bleiben die Transistoren auf jeden Fall unter allen Umständen bei einem LOW gesperrt. Man kann die entsprechenden Positionen auf der Platine aber natürlich auch mit einer Drahtbrücke bestücken. Theoretisch wären dann die Widerstände zwischen Basis und Masse auch nicht unbedingt erforderlich.
ustoni
Auserwählter
Auserwählter
Beiträge: 2105
Registriert: Sa, 04.06.11, 12:39
Wohnort: Mechernich

So, 12.03.17, 10:32

Und hier abschließend noch ein Softwareupdate.
Ich habe das Programm jetzt so abgeändert, dass man im Effektmodus die Verzögerungszeit ändern kann.
An der normalen Betriebsart als Leuchte hat sich nichts geändert.
In der Effektbetriebsart haben die Tasten jetzt folgende Funktionen:

- Taste Effekt: schaltet wie gehabt die Effekte um
- Taste Up: beendet wie gehabt den Effektmodus
- Taste Down: mit jedem Tastendruck wird die Verzögerungszeit um 25 Millisekunden verringert. Die kürzeste Zeit ist dabei 25 msec, bei erneutem Tastendruck wird dann eine Zeit von 200 msec eingestellt. Diese kann dann wieder um je 25 msec verringert werden. Beim Einschalten der Leuchte wird eine Verzögerungszeit von 100 msec eingestellt.

Edit:
Vorab noch eine Info:
Für Programme dieser Größenordnung muss man nicht unbedingt die Vollversion von BASCOM kaufen. Meist reicht auch die kostenlose Demo-Version, die man hier downloaden kann:
http://www.mcselec.com/index.php?option ... ad&gid=139
Einzige Einschränkung: der eigentliche Programmcode ist auf maximal 4096 Byte (4 kB) begrenzt. Zum Vergleich: das nachfolgende Programm hat in kompilierter Form eine Größe von 2068 Byte. Geeignete Programmer bzw. deren Bauanleitungen findet man im Netz zuhauf.

Hier jetzt das Programmlisting.

Die unveränderten Programmzeilen sind wie gehabt in blauer Schrift dargestellt, die Textfarbe von Änderungen und zusätzlichen Programmzeilen ist rot:


' Programm: Lichtbandsteuerung
' Funktion: 10-Step-Dimmung + Effektprogramme
' Controller: Mega8A
'--------------------------------------------------
' $regfile teilt dem BASCOM-Compiler mit, welcher Prozessor verwendet wird
' $crystal teilt dem Compiler mit, mit welcher Taktfrequenz der Prozessor arbeitet
$regfile = "M8adef.dat" ' Mikrokontroller
$crystal = 1000000 ' Taktfrequenz
' Hardware- und Softwarestack:
$hwstack = 48
$swstack = 32
$framesize = 60

'
' Ports konfigurieren:
' --------------------
' Wird kein spezifischer Pin angegeben, werden alle Leitungen
' des Ports gleichartig konfiguriert. Bei Angabe eines Pins
' (z.B. .0) wird nur dieser einzelne Pin konfiguriert.
Config Portb = Output ' LED9, 10
Config Portd = Output ' LED1-8
Config Portc.0 = Input ' Taste UP
Config Portc.1 = Input ' Taste DOWN
Config Portc.2 = Input ' Taste EFFEKT
Config Portc.3 = Output ' Buzzer
'
' Pull-Up-Widerstände für Taster schalten:
' ----------------------------------------
' Mit PORTx.y=1 wird ein als Output definierter Port auf High gesetzt.
' Ist dieser Port als Input konfiguriert, wird mit der gleichen
' Befehlszeile der interne Pull-Up-Widerstand zwischen den Pin und
' VCC geschaltet
Portc.0 = 1
Portc.1 = 1
Portc.2 = 1

'
' Namen für Ports vergeben:
' -------------------------
' Mit dem Befehl Alias wird dem rechts vom Befehl stehenden Port oder Pin
' der links stehende Name zugeordnet. Dies erleichtert sowohl die
' Programmierung als auch die Lesbarkeit des Programms.
Led1 Alias Portd
Led2 Alias Portb
Up Alias Pinc.0
Down Alias Pinc.1
Effekt Alias Pinc.2
Buzzer Alias Portc.3

'
' Variablen deklarieren:
' ----------------------
' Zählervariable für Helligkeit im Standardbetrieb
Dim Count As Byte
' Zählervariable für Effekte
Dim Effcount As Byte
' Statusvariable für Effektbetrieb, 0=Standard, 1=Effekt
Dim Eff As Byte
' Statusvariable für Art des Effekts
' 1 = Lauflicht
' 2 = Doppel-Lauflicht
' 3 = Wischer
' 4 = Nightrider
' 5 = Stroboskop
Dim Effektnr As Byte
' Verzögerungszeit in Effekten
Dim Zeit As Byte
' Arrays für Standardbetrieb
Dim L1(10) As Byte ' für LED 1 - 8
Dim L2(10) As Byte ' für LED 9 und 10
' Arrays für Effektbetrieb
Dim E11(10) As Byte
Dim E12(10) As Byte
Dim E21(10) As Byte
Dim E22(10) As Byte
Dim E31(10) As Byte
Dim E32(10) As Byte
Dim E41(18) As Byte
Dim E42(18) As Byte

'
' Variablen initialisieren
' ------------------------
' Hinweis: bei Programmstart werden alle deklarierten Variablen auf den Wert
' Null gesetzt. Dieser Wert muss deshalb nicht explizit vergeben werden.
'
' Anfangshelligkeit = 50%:
Count = 5
'
' Effektart Lauflicht als Startwert:
'
Effektnr = 1
' Verzögerungszeit Effekte bei Start: 100 msec:
'
Zeit = 100
' Array für Helligkeit (binär, weil besser lesbar):
L1(1) = &B00000001
L1(2) = &B00000011
L1(3) = &B00000111
L1(4) = &B00001111
L1(5) = &B00011111
L1(6) = &B00111111
L1(7) = &B01111111
L1(8) = &B11111111
L1(9) = &B11111111
L1(10) = &B11111111

'
L2(9) = &B00000001
L2(10) = &B00000011

'
' Array für Effekt1 (Lauflicht):
E11(1) = &B00000001
E11(2) = &B00000010
E11(3) = &B00000100
E11(4) = &B00001000
E11(5) = &B00010000
E11(6) = &B00100000
E11(7) = &B01000000
E11(8) = &B10000000
E11(9) = &B00000000
E11(10) = &B00000000

'
E12(9) = &B00000001
E12(10) = &B00000010

'
' Array für Effekt2 (Doppel-Lauflicht):
E21(1) = &B00000011
E21(2) = &B00000110
E21(3) = &B00001100
E21(4) = &B00011000
E21(5) = &B00110000
E21(6) = &B01100000
E21(7) = &B11000000
E21(8) = &B10000000
E21(9) = &B00000000
E21(10) = &B00000000

'
E22(8) = &B00000001
E22(9) = &B00000011
E22(10) = &B0000010

'
' Array für Effekt3 (Wischer):
E31(1) = &B00000001
E31(2) = &B00000010
E31(3) = &B10000100
E31(4) = &B01001000
E31(5) = &B00110000
E31(6) = &B00110000
E31(7) = &B01001000
E31(8) = &B10000100
E31(9) = &B00000010
E31(10) = &B00000001

'
E32(1) = &B00000010
E32(2) = &B00000001
E32(9) = &B00000001
E32(10) = &B00000010

'
' Array für Effekt4 (Nightrider):
E41(1) = &B00000001
E41(2) = &B00000010
E41(3) = &B00000100
E41(4) = &B00001000
E41(5) = &B00010000
E41(6) = &B00100000
E41(7) = &B01000000
E41(8) = &B10000000
E41(9) = &B00000000
E41(10) = &B00000000
E41(11) = &B00000000
E41(12) = &B10000000
E41(13) = &B01000000
E41(14) = &B00100000
E41(15) = &B00010000
E41(16) = &B00001000
E41(17) = &B00000100
E41(18) = &B00000010

'
E42(9) = &B00000001
E42(10) = &B00000010
E42(11) = &B00000001
'

' Endlosschleife innerhalb DO - LOOP
' ----------------------------------
' Hier werden für Standardbetrieb die Tasten abgefragt und die LEDs
' geschaltet. Auswertung der Tasten und Effekte laufen in
' eigenen Subroutines (Unterprogramme).
Do
'
' LEDs abhängig von der Variablen Count schalten:
Led1 = L1(Count)
Led2 = L2(Count)

'
' Tasten abfragen:
' ----------------
' Zum Abfragen der Tasten wird der Befehl DEBOUNCE verwendet.
' Syntax:
' Debounce, Portpin, Wert (0/1), Subroutine, Sub
' Der Portpin ist der abzufragende Pin.
' Wert ist der erwartete Wert bei gedrückter Taste. Ist die Taste z.B.
' gegen Masse (GND) geschaltet, ist der erwartete Wert bei gedrückter
' Taste 0.
' Subroutine ist der Name des Unterprogramms, das bei gedrückter Taste
' ausgeführt wird. Sub schließt den Befehl ab.
' Der Debounce-Befehl führt eine automatische Tastenentprellung durch.
' Wurde z.B. als Wert 0 angegeben, wird bei einer 1 sofort die folgende
' Programmzeile ausgeführt. Wird aber bei Ausführung des Befehls eine 0
' detektiert, wartet der Befehl 25 ms (diese Zeit ist mit Config Debounce
' änderbar, 25 ms ist Default) und überprüft den Pin dann erneut. Nur
' wenn jetzt immer noch eine 0 anliegt, wird das Unterprogramm ausgeführt.
' So wird der Tastendruck entprellt. Der Befehl wird erst dann erneut
' ausgeführt, wenn nach den 25 ms eine 1 detektiert wurde. Dadurch wird
' verhindert, dass der Befehl bei gedrückt gehaltener Taste ungewollt
' mehrfach ausgeführt wird.
'
Debounce Up , 0 , Oben , Sub
Debounce , Down , 0 , Unten , Sub
Debounce , Effekt , 0 , Effekttaste , Sub

'
' Zum Effektmodus springen, wenn Statusvariable Eff=1:
'
If Eff = 1 Then
Gosub Effektmodus
End If

'
Loop
'
' Unterprogramme:
' ---------------
'
' Subroutine Oben wird bei Drücken der Taste Up angesprungen.
' -----------------------------------------------------------
'
Oben:
'
' Variable Count um 1 verkleinern:
'
Decr Count
'
' Überlauf, wenn Count = 0:
'
If Count = 0 Then
Count = 10
End If

'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0

'
Return
'
' Subroutine Unten wird bei Drücken der Taste Down angesprungen.
' --------------------------------------------------------------
'
Unten:
'
' Variable Count um 1 vergrößern:
'
Incr Count
'
' Überlauf, wenn Count = 11
'
If Count = 11 Then
Count = 1
End If

'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0

'
Return
'
' Subroutine Effekttaste wird bei Drücken der Taste Effekt angesprungen.
' ----------------------------------------------------------------------
'
Effekttaste:
'
' Statusvariable Eff auf 1 setzen:
'
Eff = 1
'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0

'
Return
'
' -----------------------
' Subroutines für Effekte
' -----------------------
'
' Subroutine Effektmodus erzeugt die Effekte abhängig von Variablen
'------------------------------------------------------------------
'
Effektmodus:
'
' Zählervariable auf 1 setzen
' Wird der Effektmodus gewählt, beginnt der Effekt dadurch immer am Anfang
'
Effcount = 1
'
' Der Effektmodus läuft in einer While-Schleife.
' Die Schleife wird automatisch verlassen, wenn die Variable Eff
' auf 0 gesetzt wird
'
while Eff = 1
'
' Effekt 1 durchführen wenn zutreffend
'
If Effektnr = 1 Then
'
' LEDs setzen und warten:
'
Led1 = E11(Effcount)
Led2 = E12(Effcount)
Waitms
Zeit
'
' Tasten abfragen:
' Tasten Up oder Down beenden den Effektmodus, Taste Effekt
' springt zum nächsten Effekt
'
Debounce Up , 0 , Effektende , Sub
Debounce , Down , 0 ,
Effektzeit , Sub
Debounce , Effekt , 0 , Effektplus , Sub
End If

'
' Effekt 2 durchführen wenn zutreffend
'
If Effektnr = 2 Then
'
' LEDs setzen und warten:
'
Led1 = E21(Effcount)
Led2 = E22(Effcount)
Waitms
Zeit
'
' Tasten abfragen:
' Tasten Up oder Down beenden den Effektmodus, Taste Effekt
' springt zum nächsten Effekt
'
Debounce Up , 0 , Effektende , Sub
Debounce , Down , 0 ,
Effektzeit , Sub
Debounce , Effekt , 0 , Effektplus , Sub
End If


'
' Effekt 3 durchführen wenn zutreffend
'
If Effektnr = 3 Then
'
' LEDs setzen und warten:
'
Led1 = E31(Effcount)
Led2 = E32(Effcount)
Waitms
Zeit
'
' Tasten abfragen:
' Tasten Up oder Down beenden den Effektmodus, Taste Effekt
' springt zum nächsten Effekt
'
Debounce Up , 0 , Effektende , Sub
Debounce , Down , 0 ,
Effektzeit , Sub
Debounce , Effekt , 0 , Effektplus , Sub
End If

'
' Effekt 4 durchführen wenn zutreffend
'
If Effektnr = 4 Then
'
' LEDs setzen und warten:
'
Led1 = E41(Effcount)
Led2 = E42(Effcount)
Waitms
Zeit
'
' Tasten abfragen:
' Tasten Up oder Down beenden den Effektmodus, Taste Effekt
' springt zum nächsten Effekt
'
Debounce Up , 0 , Effektende , Sub
Debounce , Down , 0 ,
Effektzeit , Sub
Debounce , Effekt , 0 , Effektplus , Sub
End If

'
' Effekt 5 durchführen wenn zutreffend
'
If Effektnr = 5 Then
'
' LEDs setzen und warten:
'
Led1 = &B11111111
Led2 = &B00000011
Waitms
3
Led1 = &B00000000
Led2 = &B00000000
Waitms
Zeit
'
' Tasten abfragen:
' Tasten Up oder Down beenden den Effektmodus, Taste Effekt
' springt zum nächsten Effekt
'
Debounce Up , 0 , Effektende , Sub
Debounce , Down , 0 ,
Effektzeit , Sub
Debounce , Effekt , 0 , Effektplus , Sub
End If

'
' Zählervariable um 1 erhöhen und auf 1 setzen wenn Überlauf:
'
Incr Effcount
If Effcount = 11 AND Effektnr < 4 then
Effcount = 1
Elseif Effcount = 19 AND Effektnr = 4 then
Effcount = 1
Elseif Effektnr = 5 then
Effcount = 1
End If

'
' While-Schleife abschließen:
'
Wend
'
' Effektmodus beenden:
'
Return
'
' Subroutine Effektende setzt Variable Eff auf 0 und beendet
' dadurch den Effektmodus
:
Effektende:
Eff = 0

'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0
Return

'
' Subroutine Effektplus inkrementiert die Variable Effektnr und
' wählt dadurch den nächsten Effekt. Überschreitet der Wert den
' maximal zulässigen Wert, wird die Variable auf 1 gesetzt
'
Effektplus:
Incr Effektnr
If Effektnr = 6 Then
Effektnr = 1
End If

'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0
Return

'
' Subroutine Effektzeit verkleinert die Variable Zeit um 25 msec
' je Tastendruck. Wird der Wert < 25 msec, wird er auf 200 msec gesetzt.
'
Effektzeit:
Zeit = Zeit - 25
If Zeit < 25 Then
Zeit = 200
End If

'
' Tastendruck mit kurzem Ton quittieren:
'
Buzzer = 1
Waitms 100
Buzzer = 0
Return

'
' Programmende:
'
End
Antworten