2013-04-26 36 views
1

我已經在Arduino中編寫了循環通過3個LED顏色燈的代碼,但它似乎(代碼)容易出錯,所以我試圖想出一個新的寫法。由於複雜性,我將堅持我想要做的phesdo代碼。那就是:在Arduino中創建一個更好的循環

If (red LED isn't max and green LED is 0 and blue LED is 0) 
    {inc red LED; update dot matrix} 
If (red LED is max and green LED isn't max and blue LED is 0) 
    {inc green LED; update dot matrix} 
If ((red LED is/has-been max but not 0) and green LED is max and blue LED is 0) 
    {dec red; update dot matrix} 
If (red LED is 0 and green LED is max and blue LED isn't max) 
    {inc blue; update dot matrix} 
If (red LED is 0 and (green LED is/has-been max but not 0) and blue LED is max) 
    {dec green; update dot matrix} 
If (red LED isn't Max and green LED is 0 and blue is Max) 
    {inc red; update dot matrix} 
If (red LED is Max and green LED is 0 and (blue LED is/has-been Max but not 0)) 
    {dec blue; update dot matrix} 

Update LED Driver; 

注:對於視覺它是一個色輪去紅 - >橙色>綠 - > teal->藍 - >粉紅 - >重複

需要說明的是,這一切是在退出取回其他數據之前僅運行一次的循環中。然後它必須返回到這個循環並且記住它所遺留的顏色位置。除此之外,將所有這些內容封裝在循環中併線性執行它將非常簡單。因爲它必須增​​加或減少一種顏色,所以如果你願意,可以理解它的顏色位置,更新LED驅動程序,然後回到增加或減少記錄停止的位置。因此,任何人都有更好的代碼方法,僞風格,除了這個複雜的if語句風格之外,我可以使用它。

+0

「所有這些都在一個只運行一次的循環中」那麼它在循環中有什麼意義呢? – ApproachingDarknessFish 2013-04-26 17:57:04

+0

沒有抱歉,這個循環,但我不得不在更新顏色坐在它之前和之後的事情。我需要改變顏色一點點更新LED驅動器,然後做其他事情,然後再回來,並更新一點,重複一遍。 – Nimjox 2013-04-26 18:01:15

+0

請勿使用循環,請使用計時器。 – 2013-04-26 18:29:29

回答

2

通過一個簡單的情況繪圖,您可以找到一個公式,根據每增加一個滴答的全局計數器將強度直接應用於單個組件,代碼如下(我剛剛寫過並沒有測試,但應該足以讓你瞭解它是如何工作):

int counter = 0; // counter you should increment on each tick 
int phases = 6; // total phases in a cycles 
int cycleLength = max_steps * phases; // total ticks in a cycle 

int currentStepOfCycle = counter % cycleLength; 
int currentPhase = currentStepOfCycle/max_steps; 
int currentStepOfPhase = currentStepOfCycle % max_steps; 

// this is how much phase shifts are performed for each primary color to have the raising line in phase 0 
int phase_shifts[3] = {2, 0, 4}; 

// for each color component 
for (int i = 0; i < 3; ++i) { 
    // shift the phase so that you have/at phase 0 
    int shiftedPhase = (currentPhase+phase_shifts[i])%phases; 

    if (shiftedPhase == 1 || shiftedPhase == 2) 
    intensity[i] = MAX; 
    else if (shiftedPhase == 0) 
    intensity[i] = currentStepOfPhase; 
    else if (shiftedPhase == 3) 
    intensity[i] = MAX - currentStepOfPhase; 
    else 
    intensity[i] = 0; 
} 

從這個想法如下:

enter image description here

通過增加一個增量,因爲需要移位對於不同顏色分量的當前階段,可以總是考慮階段0,1,2和3,以瞭解強度應當提高,降低或者設置爲每個部件的最大值。

這應該適應任何你想輕鬆應用強度的步驟。

+0

我喜歡這種方法,但是什麼時候會(movesPhase == 1 && shiftedPhase == 2)? – 2013-04-26 18:21:58

+0

@GradyPlayer:這是一個'||',sry – Jack 2013-04-26 18:23:04

+0

超高速插孔,感謝您的繪製。這真的有助於解釋你是如何提出你所做的代碼的。這非常有幫助。 – Nimjox 2013-04-26 18:37:29

2

是啊,這不是很大......我會做這樣的事情..

typedef struct{ //maybe stick this in a union, depending on what the compiler does to it. 
    unsigned char r:2; 
    unsigned char g:2; 
    unsigned char b:2; 
}color; 
const int numOfColors = 3; 
color colors[numOfColors] = { 
    {2,0,0},//r 
    {1,1,0},//o 
    {0,2,0}//g 
}; 

for(int i = 0 ; 1 ; i++) 
{ 
    color c = colors[i%numOfColors]; 
    //set color 
    //update 
    //wait 
} 
+1

至少在我閱讀它時,LED不僅僅是開啓或關閉 - 我相信他對每個LED都有兩個「開啓」級別(但我可能會誤解LED的組合)。 – 2013-04-26 18:07:15

+0

@JerryCoffin是的,我不確定這個......我想你可以使用2位,並有一個/半/關狀態,你仍然可以操作相同的基本方式,雖然...與緩存/查找,而不是多枝易錯的噁心。 – 2013-04-26 18:10:53

+0

是的 - 它仍然是一個國家的計數器,並在某個級別上驅動每個LED在任何給定的狀態。 – 2013-04-26 18:12:35

2

至少我看了你的if語句,你有7種不同狀態(也許它應該是8?),和當你到達最後,它會繞回到第一個。

這很容易實現作爲一個計數器與一個小型查找表映射從一個國家號碼應該點亮一個州的狀態。