Guten Morgen,
da immer wieder mal die Frage nach einem LED-Fader hier kommt, möchte ich mal eine kleine Schaltung dazu vorstellen.
Das Projekt besteht schon ein wenig länger, hatte es im Netz auch schon mal vorgestellt....
Das Modul ist so konzipiert, dass zwei Ausgänge seperat dimmbar sind und bis zu 3 Blinkeffekte abgerufen werden können.
Der Schaltplan ist recht übersichtlich, im wesentlichen ist das Herzstück der Attiny13. Dieser wurde jedoch im Laufe des Projekts durch Attiny25 ersetzt, da ich für diesen bessere Beschaffungsquellen hatte und zu dem mehr Flash Speicher zur Verfügung steht.
Der Dimmer hat einen 5V Spannungsregler und kann mit 12V versorgt werden. An den Ausgängen steht die eingespeiste Spannung an.
Zum Schaltplan gehört natürlich, dann auch ein Layout
Teileliste:
X1,2,3 Printstecker 3 polig
X4 Pin1 Versorgungsspannung 12V
X4 Pin2 Versorgungsspannung GND
X5 Pin1 + Anschluss der Last (12V)
X5 Pin2 - Anschluss der Last
X6 Pin1 + Anschluss der Last (12V)
X6 Pin2 - Anschluss der Last
Fuse Kleinsicherung Je nach Last!
C1 Folienkondensator 330nF
C2 Folienkondensator 100nF
C3 Folienkondensator 100nF
IC1 Attiny25 mit Dimmsoftware
IC2 Spannungsregler 7805
T1 IRLZ34N
T2 IRLZ34N
R1 240 Ohm
R2 16K Ohm
R3 240 Ohm
R4 16K Ohm
Die Taster müssen an X1-2,X1-3 (Effekt) an X2-2,X2-3 Dimmer(1) und an X3-1,X3-3 Dimmer(2).
X1 u. X2 ist so vorbereitet, dass auch die Steuerung über Potis möglich ist.
Allerdings haben wir dazu keine Firmware gemacht.
Auf eine ISP Schnittstelle wurde hier verzichtet.
Schreiten wir zum nächsten Schritt, ein Foto von der bestückten Platine:
Anschließend habe ich die Platine in ein Gehäuse integriert
Aber was macht eine Platine ohne Software? Natürlich gar nix!
Deshalb ist in dem angehängten Ordner neben Schaltplan und Layout auch das Hexfile zu finden.
Bedienungsanleitung
Effektauswahl:
Über den Taster Effektauswahl kann zwischen 4 Effekten gewählt werden:
1.Dimmermodus
2.Blinker
3.Wechselblinker
4.Fader
Bei einem weiteren Tastendruck bei Effekt 4 wird wieder Effekt 1 aufgerufen.
Effekt Dimmermodus:
Im Effekt Dimmermodus kann über Dimmer1 und Dimmer2 die Helligkeit der beiden Ausgänge durch Tastendruck einzeln verstellt werden.
Effekt 2-4:
Bei diesen Effekten kann mit Taster Dimmer1 die Geschwindigkeit des Effekts und mit Dimmer2 die Helligkeit der LED Beleuchtung gesteuert werden.
Hier noch ein Link wie die Software übertragen werden kann.
Vielleicht ist diese Schaltung ja für den ein oder andern von euch von Nutzen
Natürlich erfolgt der Nachbau wie immer auf eigene Gefahr
Code: Alles auswählen
/*
* main.c
*
* Created on: 20.10.2009
* Version: 0.1.0
* Author: tecdroid
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>
#include <math.h>
#define INTERRUPTING
/***************************** /
* Zeiten für die Wellenform
****************************/
#define DIFS 100
#define SEC1 28
#define SEC2 SEC1 + DIFS
#define SEC3 SEC1 + SEC2
/***************************** /
* Konfiguration der Pins
****************************/
// PB2 ist die Taste
#define PB_TASTE1 PB2
#define PINB_TASTE1 PINB2
// ADC2 - ist immer die Dimmung
#define PB_TASTE2 PB3
#define PINB_TASTE2 PINB3
// ADC3 - ist Dimmung oder Frequenz
#define PB_TASTE3 PB4
#define PINB_TASTE3 PINB4
#define VAL(x) ( (uint16_t)x * (uint16_t)valLeft / DIFS)
/***************************** /
* Konfiguration des Blinkers
****************************/
// der auszuführende effekt
enum {
DIMMER = 0,
BLINKER = 1,
WECHSELBLINKER = 2,
FADER = 3,
WECHSELFADER = 4,
count = 5
} effekt;
// die ADC-Werte
uint8_t valLeft;
uint8_t valRight;
uint8_t timer;
uint16_t timer2;
/***************************** /
* Funktionen
****************************/
void init_taste(void) {
/* Die Tastenpins als Input konfigurieren und
* PULLUPs aktivieren
*/
DDRB &= ~((1 << PB_TASTE1) | (1 << PB_TASTE2) | (1 << PB_TASTE3));
PORTB |= (1 << PB_TASTE1 | (1 << PB_TASTE2) | (1 << PB_TASTE3));
}
/* Entprellter Tastendruck
*/
uint8_t tasteGedrueckt(uint8_t pTaste) {
/* Wenn Pin B0 low ist, wurde der Taster gedrückt
*/
uint8_t input = ~PINB;
if (input & pTaste) {
_delay_ms(50);
/* warte bis losgelassen wurde
*/
while (~PINB & pTaste) {
_delay_ms(50);
}
/* warte um das Loslassen zu entprellen
*/
_delay_ms(50);
/* melde den Tastendruck
*/
return (input & pTaste);
}
/* wurde die Taste nicht gedrückt
* melde negatives Ergebnis
*/
return 0;
}
/*
* initialisiert die PWM
*/
void init_pwm() {
/* OCR0A&B als Ausgang konfigurieren. */
DDRB |= (1 << PB0) | (1 << PB1);
/* OCR0A&B als invertierender Ausgang der PWM konfigurieren */
TCCR0A |= (1 << COM0A1) | (1 << COM0B1);
/* FastPWM konfigurieren */
TCCR0A |= (1 << WGM00);
/* Vorteiler auf 8, 4KHz *
TCCR0B = (1 << CS01);
*/
/* Vorteiler auf 64, 0.5KHz */
TCCR0B = (1 << CS01) << (1 << CS00);
/* Timer-Interrupt deaktivieren */
TIMSK &= ~((1 << OCIE0A) | (1 << OCIE0B));
}
/*
* initialisiere den Timer 1
*/
void init_timer() {
/* Vorteiler auf 8 */
TCCR1 = (1 << CS12);
/* Timer Overflow interrupt aktivieren */
TIMSK |= (1 << TOIE1);
}
/*
* setzen der linken LED
*/
inline void set_left_value(uint8_t val) {
OCR0A = val;
}
/*
* setzen der rechten LED
*/
inline void set_right_value(uint8_t val) {
OCR0B = val;
}
inline void calc_value() {
// erhöhe den timer
if (effekt == DIMMER) {
timer2 = 0;
timer = 0;
} else {
timer2 += valRight + 1;
timer = (timer2 >> 8);
}
// führe die zum aktuellen Effekt gehörende Funktion aus
switch (effekt) {
case BLINKER:
if ((timer < 0x80)) {
set_left_value(valLeft);
set_right_value(valLeft);
} else {
set_left_value(0);
set_right_value(0);
}
break;
case WECHSELBLINKER:
if ((timer < 0x80)) {
set_left_value(valLeft);
set_right_value(0);
} else {
set_left_value(0);
set_right_value(valLeft);
}
break;
case FADER:
if (timer < SEC1) {
// nullstellung
set_left_value(0);
set_right_value(0);
} else if(timer < SEC2) {
// steigende Flanke
set_left_value(VAL(timer - SEC1));
set_right_value(VAL(timer - SEC1));
} else if (timer < SEC3) {
// maximalwert
set_left_value(VAL(DIFS - 1));
set_right_value(VAL(DIFS - 1));
} else {
// fallende Flanke
set_left_value(valLeft - VAL(timer - SEC3));
set_right_value(valLeft - VAL(timer - SEC3));
}
break;
case WECHSELFADER:
if (timer < SEC1) {
// nullstellung
set_left_value(0);
set_right_value(VAL(DIFS -1));
} else if(timer < SEC2) {
// steigende Flanke
set_left_value(VAL(timer - SEC1));
set_right_value(valLeft - VAL(timer - SEC1));
} else if (timer < SEC3) {
// maximalwert
set_left_value(VAL(DIFS -1));
set_right_value(0);
} else {
// fallende Flanke
set_left_value(valLeft - VAL(timer - SEC3));
set_right_value(VAL(timer - SEC3));
}
break;
default:
set_left_value(valLeft);
set_right_value(valRight);
break;
}
}
/*
* Timerfunktion
*/
ISR(TIMER1_OVF_vect)
{
calc_value();
}
/***************************** /
* Hauptprogramm
****************************/
int main() {
// initialisiere Maschine
init_pwm();
init_taste();
// initialisiere Werte
effekt = DIMMER;
valLeft = 0x1;
valRight = 0x1;
// aktiviere Interrupts
#ifdef INTERRUPTING
init_timer();
sei();
#endif
// starte Ablauf
while (1) {
// bei Tastendruck ändert sich der Effekt
if (tasteGedrueckt(1 << PINB_TASTE1)) {
effekt++;
if (effekt == WECHSELFADER) {
effekt = DIMMER;
}
}
// bei Tastendruck ändert sich der Effekt
if (tasteGedrueckt(1 << PINB_TASTE2)) {
if (valLeft == 0xff) {
valLeft = 0x00;
} else {
valLeft = (valLeft << 1) + 1;
}
}
// bei Tastendruck ändert sich der Effekt
if (tasteGedrueckt(1 << PINB_TASTE3)) {
if (valRight == 0xff) {
valRight = 0x00;
} else {
valRight = (valRight << 1) + 1;
}
}
#ifndef INTERRUPTING
calc_value();
// warte
_delay_ms(1);
#endif
Gruß Flo