2014-04-25 57 views
0

在Arduino的Esplora,這是基於萊昂納多板,支持PWM引腳5的驅動的RGB LED的紅色成分看起來這股帶有計時器功能tone。這會產生意想不到的後果,即在播放音調後呈現紅色組件無用,因爲其行爲變得無法預測。你如何阻止Arduino的Esplora的音功能與RGB干擾LED

下面是一個簡單setup例行演示問題:

void setup() 
{ 
    //analogWrite(5, 255); 
    //delay(1000); 
    analogWrite(5, 1); 
    delay(2000); 
    Esplora.tone(440); 
    delay(1000); 
    Esplora.noTone(); 
} 

這將打開LED來的最低設置的紅色通道並保持兩秒鐘,然後播放了1/4的440 Hz的音調第二,但只要音調開始,而不是保持低亮度,LED將完全熄滅。

如果取消註釋前兩行,這個時候的語氣開始,而不是(錯誤地)爲前關閉,現在(同樣不正確地)轉向回全屏亮度。

調用tone後,我無法找出如何恢復的紅色成分的適當的功能(或上引腳5更具體PWM)。

我的猜測是產生聲音的正確HZ,tone改變定時器,然後影響到PWM功能的設置。如果我可以找出如何手動重置定時器以正確支持LED的PWM,那可能是解決方案。然而,我對Arduino,定時器和類似的新手很陌生,所以這是純粹的猜測,我可能完全錯用了這種方法或者我對它的理解,但從我讀過的內容來看,這看起來確實是正確的方向。 。

因此,任何人都知道如何在該引腳上恢復正確的PWM功能?

馬克

+0

什麼是TCCR3A,TCCR3B,TCCR4A,TCCR4B,TCCR4C,TCCR4D的價值觀,TCCR4E前和故障後(十六進制請)? –

+0

Arduino的新手。我如何檢查這些?任何草圖代碼將不勝感激。 (你是誰投我倒?如果是這樣,請仔細解釋爲什麼??) – MarqueIV

+0

只需通過串行連接輸出它們。 –

回答

1

我學的是32U4文檔一點,從他們使用的啓動給init PWM資源Arduino的庫搶下Esplora特定的邏輯。下面生成的timerFix()例程可以用來恢復正確的設置。

void loop() 
{ 
    Esplora.writeRGB(127,0,0); 
    delay(1000); 
    Esplora.tone(311); 
    delay(1000); 
    timerFix(); 
    Esplora.writeRGB(32,0,0); 
    delay(1000); 
} 
void timerFix() 
{ 
    #define sbi(sfr,b) (_SFR_BYTE(sfr) |= _BV(b)) 

    //Tone will have hijacked the timer used for the 
    //RGB led RED channel so once we're done we need 
    //to restore it. First shutdown the tone internals 
    //if not done already... 
    Esplora.noTone(); 

    //Now clear the Timer Count Control Registers to 
    //have them in a known state. 
    TCCR3A = 0; 
    TCCR3B = 0; 

    //Setup the clock source - clk/64 
    sbi(TCCR3B, CS31); 
    sbi(TCCR3B, CS30); 

    //Set the wave form generator for 10-bit PWM 
    sbi(TCCR3A, WGM30); 

    //re-link the PWM timer to output channel 
    //by passing something other than 0 and 255 
    //so that the analogWrite function is forced to 
    //recompute the correct value for either the 
    //OCR3A or OCR3B register (output control register) 
    //as appropriate 
    analogWrite(5, 1); 

    //turn the LED channel off 
    analogWrite(5, 0); 
} 
1

你懷疑關於tone()重新配置定時器是正確的。在'32U4上,定時器3用於tone(),但在Esplora上,OC3A用於紅色組件(OC1B和OC1A分別用於綠色和藍色組件)。這意味着每次在Esplora上調用tone()時,定時器3被重新配置爲CTC(WGM3 [3:0] = 0b0100),而紅色組件需要PWM才能正確使用(並且analogWrite()專門使用8位相位 - 正確的PWM [WGM [3:0] = 0b0001])。由於需要定時器直到音調停止,所以沒有任何理智的方式在模式之間來回切換。

通常情況下解決這一問題的最簡單的方法是告訴tone()使用不同的定時器。不幸的是在Esplora沒有計時器,它可以使用:定時器0使用delay()等人,定時器1使用由綠色和藍色分量,定時器4件作品完全不同比Arduino的庫編程,和。定時器2甚至不存在於'32U4上。

但是,'32U4上的OC3A引腳與nOC4A引腳相同。這意味着我們可以使用定時器4來控制紅色組件。當您檢查TCCR4 *時,它們的值不是0,但這可能是因爲引導加載程序與它們一起擺弄;我無法在修改它們的Arduino核心或Esplora庫中找到任何東西。

有2個問題與使用計時器4:

  1. 引腳13連接到OC4A。這意味着引腳13必須始終配置爲輸入,因爲它的輸出將是與紅色分量相反的PWM信號。

  2. Arduino的庫沒有被編程用於處理定時器4。這意味着我們需要在低級別訪問定時器4配置和使用它。

所以:

pinMode(13, INPUT); 
// disable timer 4 interrupts 
TIMSK4 = 0; 
// reset TCCR4C 
TCCR4C = 0; 
// set OCR4C to maximum 
OCR4C=0xff; 
// clear dead time register 
DT4 = 0; 
// enable PWM based on OCR4A and connect nOC4A (and OC4A) 
TCCR4A = _BV(PWM4A) | _BV(COM4A0); 
// match analogWrite() prescaling 
TCCR4B = _BV(CS42) | _BV(CS41) | _BV(CS40); 
// enable fast PWM 
TCCR4D = 0; 
// set minimum brightness 
OCR4A = 0xff; 

delay(1000); 
OCR4A = 0xbf; // low brightness 
delay(1000); 
OCR4A = 0x3f; // high brightness 
delay(1000); 
OCR4A = 0x7f; // mid brightness 
delay(1000); 
OCR4A = 0x00; // max brightness 
+0

伊格納西奧嗨!對於這個問題,這是一個非常好的寫法。你實際上已經超越了,並且超越了我所需要的,這只是在播放音調之後重新配置Timer3以用於PWM。原因是,當我在Esplora上進行原型設計時,我想屏蔽任何可能成爲問題的董事會。但是這對於更改/更新來說太好了,所以我可以通過一個簡單的代碼片斷來創建第二個關於如何重新配置​​定時器以回到支持PWM的片段?如果必須,我只需在音調和RGB之間切換,而不是在播放聲音時使用LED。 – MarqueIV

+0

此外,雖然這不能解決我的緊急需求,但我仍然對理解您在此處所做的工作感興趣。你能否就OCR4A之類的事情擴展評論?我在google搜索,但我似乎無法找到定時器的好教程,以及所有這些值如何相關。 – MarqueIV

+0

另一件事......在上面關於引腳13的'警告'中,通常是默認的LED引腳。將它作爲輸出看到紅色的倒數是否有任何傷害?它會攪亂什麼,或者你只是這樣做,所以你不會看到它? – MarqueIV