使用Arduino在均匀流动中随着时间的推移调暗LED

时间:2014-02-07 09:28:45

标签: arduino pwm

我试图弄清楚如何随着时间的推移调暗LED(时间由用户定义,让我们称之为rampUp)。我正在使用arduino和adafruit breakout PWM-Servo-Driver(http://www.adafruit.com/products/815)和库:https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library

这个突破有4095步(0-4095)所以现在我的问题:

我希望能够获取一个变量(int minutes)并将其发送到一个方法,该方法将LED在0到4095之间以相同的光强度增加调整一段时间。我希望每次增加时增量都会增加1。

那么如何在不使用delay()的情况下编写方法?

void dimLights(int rampUp){
  // some code to regulate the increase of the third value in setPWM one step at a time over a period of rampUp(int in minutes)
  led.setPWM(0,0,4095);
}

不想使用delay()的原因是因为它会暂停/停止程序的其余部分。

1 个答案:

答案 0 :(得分:0)

我最近实现了一些近距离的事情:

void loop() {
    /* ... */
    if (rampUp != 0)
        led.setPWM(0,0,rampUp);
}

void led_update() {
    // here you can prescale even more by using something like
    // if (++global_led_idx == limit) {
    //   global_led_idx = 0;
    ++rampUp;
}

void start() {
    TCCR1B |= _BV(WGM12);
    // set up timer with prescaler = FCPU/1024 = 16MHz/1024 ⇒ 60ms
    TCCR1B |= _BV(CS12) | _BV(CS10);
    TCCR1B &= ~_BV(CS11);

    // initialize counter
    OCR1A = 0x0000;

    // enable global interrupts
    sei();
    // enable overflow interrupt
    TIMSK1 |= _BV(OCIE1A);
}

void TAGByKO_LED::stop() {
    TIMSK1 &= ~_BV(OCIE1A);
    rampUp = 0;
}

ISR(TIMER1_COMPA_vect, ISR_NOBLOCK) {
    led_update();    
}

然后您可以调用start()启动计时器,或stop()停止计时器。您可以阅读有关我在此处使用的寄存器和ISR语句的更多文档。请注意,这是真正理解的AVR最棘手的事情之一,即使这样,你也总是需要附近的备忘单或数据表。

您也可以将@ sr-richie的解决方案与定时器一起使用,但只在dimLights()函数中设置变量,并仅在led.setPWM()内调用loop()