Ja ok gern.
Aber nicht lachen, der Code funktioniert bei beliebigen Geschwindigkeiten.
Kurz zur Vorgeschichte: Dieser Code ist Teil eines Steuergerätes, das eine Unmenge an LEDs als Zimmerbeleuchtung steuern kann. Und zwar frei dimmbar von 0% auf 100%. Zudem gibt es zwei LED-Stromkreise, einen blauen und einen weißen. (Für romantisches und helles Licht) - Edit: Ich sehe gerade, den weißen Codeteil habe ich gestrichen, da ich für jemanden anderes nur die romantische Variante gebaut habe.
Wenn man die Encoder drückt, dimmt er das Licht an oder aus. Und nur, wenn das Licht an ist, kann man mittels drehen die Helligkeit steuern. Dreht man über 100% oder 0% hinaus, so ertönt ein Geräusch.
Achtung, unvollständig - Das Programm ist im kompletten sehr groß.
Code:
#define PIN_ENCODER PINB
// Blauer Encoder linker Kanal, rechter Kanal, Masse
#define PIN_ENCODER_B_L 1
#define PIN_ENCODER_B_GND 2
#define PIN_ENCODER_B_R 3
// Blauer Encoder Button
#define PIN_ENCODER_B_BTN 0
#define PIN_ENCODER_B_BTN_GND 4
// Ausgang für den blauen Stromkreis
#define PIN_PWM_B 3
// Sind beide Kanäle auf '1'?
#define ENC_B_BOTH (_BV(PIN_ENCODER_B_L) | _BV(PIN_ENCODER_B_R))
// Ist der linke Kanäle auf '1'?
#define ENC_B_LEFT _BV(PIN_ENCODER_B_R)
// Ist der rechte Kanäle auf '1'?
#define ENC_B_RIGHT _BV(PIN_ENCODER_B_L)
// Hilfsmakro
#define FILTER_ENC_B (PIN_ENCODER & ENC_B_BOTH)
#define PWM_CHANGE_VALUE 25
// Aktueller Programmzustand
#define MODE_OFF 0
#define MODE_FADE_IN 1
#define MODE_ON 3
#define MODE_FADE_OUT 4
SIGNAL (SIG_PCINT)
{ // BTN blue pressed
if (PIN_ENCODER & PIN_ENCODER_B_BTN) // Nur bei LOW!
return;
if (blue_pwm_mode == MODE_FADE_IN || blue_pwm_mode == MODE_FADE_OUT)
return;
if (blue_pwm_mode == MODE_OFF)
{
blue_pwm_mode = MODE_FADE_IN;
pwm_fadewert_blue = 0;
}else{
blue_pwm_mode = MODE_FADE_OUT;
pwm_fadewert_blue = pwm_wert_blue;
}
pin_changed = 1;
}
int main(void)
{
uint8_t oldB;
uint8_t newB;
uint8_t peep_no;
unsigned int* rot;
rot = &OCR1A;
pins_init();
timer1_init();
sei();
_delay_ms(250);
peep_ack();
peep_ack();
oldB = FILTER_ENC_B;
while (1)
{
if (pin_changed)
{
pin_changed = 0;
peep_ack();
}
// MODE_ON heißt, die Lampen sind an
if (blue_pwm_mode == MODE_ON)
if (FILTER_ENC_B != oldB)
{
newB = FILTER_ENC_B;
peep_no = 0;
if ((newB == ENC_B_BOTH) && (oldB == ENC_B_LEFT))
{
if (pwm_wert_blue >= PWM_CHANGE_VALUE+1)
pwm_wert_blue -= PWM_CHANGE_VALUE;
else
peep_no = 1;
}else if ((newB == ENC_B_BOTH) && (oldB == ENC_B_RIGHT)){
if (pwm_wert_blue < 255-PWM_CHANGE_VALUE+1)
pwm_wert_blue += PWM_CHANGE_VALUE;
else
peep_no = 1;
}else if ((newB == 0) && (oldB == ENC_B_RIGHT)){
if (pwm_wert_blue >= PWM_CHANGE_VALUE+1)
pwm_wert_blue -= PWM_CHANGE_VALUE;
else
peep_no = 1;
}else if ((newB == 0) && (oldB == ENC_B_LEFT)){
if (pwm_wert_blue < 255-PWM_CHANGE_VALUE+1)
pwm_wert_blue += PWM_CHANGE_VALUE;
else
peep_no = 1;
}
if (peep_no == 1)
peep_ack();
oldB = FILTER_ENC_B;
}
}
}
Falls es jemanden interessiert, hier ist der Part für die Software-PWM
Code:
SIGNAL (SIG_OUTPUT_COMPARE0A)
{
static uint8_t pwm_counter;
pwm_counter++;
if (blue_pwm_mode == MODE_ON && pwm_wert_blue >= pwm_counter)
{
PORT_PWM |= _BV(PIN_PWM_B);
}else
if (blue_pwm_mode != MODE_OFF && blue_pwm_mode != MODE_ON && pwm_fadewert_blue >= pwm_counter)
{
PORT_PWM |= _BV(PIN_PWM_B);
}else
PORT_PWM &= ~_BV(PIN_PWM_B);
if (pwm_counter == 255)
{
if (blue_pwm_mode == MODE_FADE_IN)
{
pwm_fadewert_blue ++;
if (pwm_fadewert_blue >= pwm_wert_blue)
blue_pwm_mode = MODE_ON;
} else if (blue_pwm_mode == MODE_FADE_OUT)
{
pwm_fadewert_blue --;
if (pwm_fadewert_blue <= 1)
blue_pwm_mode = MODE_OFF;
}
}
}
Lesezeichen