2013-01-11 135 views
0

我正在試驗下面的代碼。我想讓我的LED慢慢消失,比如2秒/ 2000毫秒。該代碼如書面所示,與循環digitalWrite(2,HIGH)digitalWrite(2,LOW)無法區分。我懷疑處理器如此迅速地拉動了255個步驟,以至於衰減持續時間不可察覺。減慢Arduino FOR循環

void setup() {      # set pin 2 as output 
    pinMode = (2,OUTPUT); 
} 

void loop() { 
    (for int fi=0;fi<255;fi++) { # fade IN pin2 from 0-254 
    analogWrite(2,fi) 
    } 
    (for int fo=0;fo<255;fo--) { # fade OUT pin2 from 0-254 
    analogWrite(2,fo) 
    } 
} 

我想提出一兩個關於如何減慢褪色和衰落的建議。我最初的想法是在每個步驟中添加delay(8) ...但是這會顯示爲更平滑的線性漸變的階躍功率增加嗎?這是否是一種最佳做法,還是有一種更可接受的方式?

還有其他想法嗎?

回答

2

是的,你是正確的,這是不可能創造真正的線性褪色與微控制器。輸出將始終有一些最小步長或分辨率。對於你來說,問題是「PWM是否有足夠的分辨率,以至於不會察覺到這些步驟?」

的PWN可以輸出0〜255級的步驟100%。這與顯示器上每個像素的8位分辨率相同。看看任何監視器校準頁面,你可能會說服自己,8位分辨率提供了基本上平滑的規模。 Example monitor gradient

因此,這裏是你的樣品變淡並每4秒關機的LED。這向您顯示了一些如何在後臺執行任務的方法。

開到關的4秒改變使用無延遲的Arduino文檔在閃爍中描述的方法。每次通過loop()都會檢查自上次更改以來的時間是否超過指定的時間間隔 - 如果是,則更改狀態並標記當前時間。

的淡入淡出實現略有不同。你留下了下一次改變發生的時間。每一個旋轉循環()你檢查是否是下一個動作的時間。如果是,則進行更改,並存儲何時進行下一次更改。

/* unfortunately standard LED on pin 13 does not have PWM 
You will need to connect an LED and resistor */ 
const int pin = 3; 

/* this is your step time between changes in light 
output in milliseconds */ 
const unsigned int tstep = 8; 

/* this is the time then next change can be made. 
The change will happen at or after this value. */ 
unsigned int tnext = 0; 

/* this is the current and target light level 
The output will slowly ramp until the current value 
meets the target. So to request that the change start, 
the code just sets a new target. */ 
unsigned int target = 0; 
unsigned int current = 0; 

/* These are from Blink without Delay 
Shows another way to execute delays. */ 
unsigned long previousMillis = 0; 
unsigned long interval = 4000; 

void setup() { 
    pinMode(pin,OUTPUT); 
    tnext = millis() + tstep; 
    analogWrite(pin, current); 
} 

/* something in the code calls this 
to request a change in the LED state 
Pass what you want to be the new value 
and the LED will slowly change to that value. */ 
void newTarget(int value) { 
    tnext = millis() + tstep; 
    target = value; 
} 

/* call this frequently to update the LED 
If the time of the next action has been reached, 
execute the change and setup when the following 
change will occur. */ 
void driveLed() { 
    unsigned int tnow = millis(); 

    if(target != current) { 
     if(tnow >= tnext) { 
     if(target > current) { 
      current += 1; 
     } 
     else { 
      current -= 1; 
     } 
     analogWrite(pin, current); 
     tnext += tstep; 
     } 
    } 
} 


/* Note that the main loop has no delays. 
Execution will spin rapidly through this, most times 
checking and finding nothing to to. 
You would add your other functionality here, and this 
LED would continue to happen. As long as you don't pack 
anything that takes on the order of 8 ms, you won't notice 
a change in the LED fade behavior. 
void loop() { 
    unsigned int tnow = millis(); 

    // some other logic here would decide when to change the LED state 
    // For this sample, just toggle every 4 seconds 
    if((tnow - previousMillis) >= interval) {   
     if(0 == target) { 
     newTarget(255); 
     } 
     else { 
     newTarget(0); 
     } 
     previousMillis = tnow; 
    } 

    driveLed(); 
} 
2

我會用萬分之一函數來獲取在發出寫了更好的控制:

http://arduino.cc/en/Reference/Micros

它不是延遲,但只是返回,因爲董事會已經通過微秒數上線了,有了它,你可以做一些邏輯是這樣的:

setup() 
{ 
    t0 = micros() 
} 


loop() 
{ 
    t1 = micros(); 
    dt = t1 - t0; 
    if (dt > SOME_SMALL_TIME_DELTA) 
    { 
     increment_or_decrement_led_value_by_one(); 
     t0 = t1 
    } 
}