2016-12-04 201 views
-2

我想要做的是同時運行2個交通燈(例如北方和南方)。除millis之外是否有延遲的替代方案?我試圖使用Blinkwithoutdelay,但作爲一個新手它使用它非常複雜。[修正] Arduino替代延遲?

digitalWrite(greenled, HIGH); //Green on for 1 seconds 
    delay(greenDuration); 
    digitalWrite(greenled, LOW); //Green off, yellow on for 1 seconds 
    digitalWrite(yellowled, HIGH); 
    delay(1000); 
    digitalWrite(yellowled, LOW); //yellow off, red on for 1 seconds 
    digitalWrite(redled, HIGH); 
    delay(1000); 
    digitalWrite(redled, LOW); //Red off 


    digitalWrite(greenled2, HIGH); //Green on for 1 seconds 
    delay(1000); 
    digitalWrite(greenled2, LOW); //Green off, yellow on for 1 seconds 
    digitalWrite(yellowled2, HIGH); 
    delay(1000); 
    digitalWrite(yellowled2, LOW); //yellow off, red on for 1 seconds 
    digitalWrite(redled2, HIGH); 
    delay(1000); 
    digitalWrite(redled2, LOW); //Red off 

完整代碼:

int beam = 2;//Beam sensor 
int greenled = 4; 
int redled = 7; 
int yellowled = 13; 
int greenDuration =1000; //normal time 
int greenShortDuration = 1000; 
int greenIncrement = 5000; //5 seconds 
void setup() 
{ 
    // set the digital pin as output: 
    pinMode(greenled, OUTPUT); 
    pinMode(redled, OUTPUT); 
    pinMode(greenled, OUTPUT); 
    pinMode(beam,INPUT); 
    Serial.begin(9600); 
} 

void loop() 
{ 
      Serial.println("Status:low"); 
      digitalWrite(greenled, HIGH); //Green on for 5 seconds 
      delay(greenDuration); 
      digitalWrite(greenled, LOW); //Green off, yellow on for 2 seconds 
      digitalWrite(yellowled, HIGH); 
      delay(1000); 
      digitalWrite(yellowled, LOW); //yellow off, red on for 5 seconds 
      digitalWrite(redled, HIGH); 
      delay(1000); 
      digitalWrite(redled, LOW); //Red and Yellow off 

    digitalWrite(greenled2, HIGH); //Green on for 1 seconds 
    delay(1000); 
    digitalWrite(greenled2, LOW); //Green off, yellow on for 1 seconds 
    digitalWrite(yellowled2, HIGH); 
    delay(1000); 
    digitalWrite(yellowled2, LOW); //yellow off, red on for 1 seconds 
    digitalWrite(redled2, HIGH); 
    delay(1000); 
    digitalWrite(redled2, LOW); //Red off 
    if(digitalRead(beam)==HIGH){ 
    for(int i=1; i<=10; i++){ 
     Serial.println(i); 

     while(i>=10){ 
      Serial.println("Motion Detected"); 
      greenDuration +=greenIncrement; //Add 5 seconds everytime 
      Serial.println(greenDuration); 

     break; 
     } 

     } 

    } 
     if(!digitalRead(beam)==HIGH){ 
     Serial.println("hey"); //indication of code is working 
     greenDuration=greenShortDuration; 
     return; 

} 

} 

固定感謝大家誰幫助

unsigned long curGoStopDuration, defGoStopDuration = 5000, maxGoStopDuration = 30000; 
unsigned long currentMillis; 

#pragma region SensorFields 
int durationIncrement = 2500; 
unsigned long greenPrevMillis; 
float DetectionTime = 2500; 
bool triggered; 
#pragma endregion 

enum LightState { Green, Yellow, Red }; 

class Stoplight 
{ 
private: 
    int greenLed, yellowLed, redLed; 
    unsigned long previousMillis; 
    float CurInterval; 
    LightState state; 
public: 
    unsigned long GreenDuration = 5000; 
    unsigned long RedDuration = 5000; 
    int YellowDuration = 1000; 

    Stoplight(int gLed, int yLed, int rLed) :greenLed(gLed), yellowLed(yLed), redLed(rLed) 
    { 
     pinMode(greenLed, OUTPUT); 
     pinMode(redLed, OUTPUT); 
     pinMode(yellowLed, OUTPUT); 
    } 

    void Loop() 
    { 
     if (currentMillis - previousMillis >= CurInterval) 
     { 
      previousMillis = currentMillis; 
      //Transitions 
      switch (state)   
      { 
       case Green:    
        ToYellow(); 
        break; 
       case Yellow: 
        ToRed(); 
        break; 
       case Red: 
        ToGreen(); 
        break; 
      } 
     } 
    } 

    void ToGreen() 
    { 
     digitalWrite(redLed, LOW); 
     digitalWrite(greenLed, HIGH); 
     CurInterval = GreenDuration - YellowDuration; 
     state = Green; 
    } 

    void ToYellow() 
    { 
     digitalWrite(greenLed, LOW); 
     digitalWrite(yellowLed, HIGH); 
     CurInterval = YellowDuration; 
     state = Yellow; 
    } 

    void ToRed() 
    { 
     digitalWrite(yellowLed, LOW); 
     digitalWrite(redLed, HIGH); 
     CurInterval = RedDuration; 
     state = Red; 
    } 

}; 

Stoplight SL_01(2, 3, 4), SL_02(5, 6, 7); 
int beamSensor = 8; 

void setup() 
{ 
    //Set default values 
    curGoStopDuration = defGoStopDuration; 

    SL_01.ToGreen(); 
    SL_02.ToRed(); 

    pinMode(beamSensor, INPUT); 
    Serial.begin(9600); 
} 

void loop() 
{ 
    currentMillis = millis(); 
    Sensor(); 

    //Manipulate durations 
    SL_01.GreenDuration = curGoStopDuration; 
    SL_02.RedDuration = curGoStopDuration; 
    SL_01.Loop(); 
    SL_02.Loop(); 
} 

void Sensor() 
{ 
    //If sensor detects something 
    if (digitalRead(beamSensor) == HIGH) 
    { 
     if (!triggered) 
     { 
      greenPrevMillis = currentMillis; 
      triggered = true; 
     } 

     if (currentMillis - greenPrevMillis >= DetectionTime) 
     { 

      if(curGoStopDuration < maxGoStopDuration) 
       curGoStopDuration += durationIncrement; //Add seconds 

      greenPrevMillis = currentMillis; 

      Serial.print("Green light duration is now: "); 
      Serial.println(curGoStopDuration); 
     } 
    } 
    else //No detection 
    { 
     curGoStopDuration = defGoStopDuration; 
     triggered = false; 
    } 
} 
+0

交通信號燈是有限狀態機最常用的示例。我建議你使用'uint8_t'變量來存儲程序的當前狀態(例如「綠色開啓」,「綠色關閉,黃色開啓」等)。您必須使用數字對它們進行編碼,例如'const uint8_t state_green_on = 1;''const uint8_t state_green_off_yellow_on = 2'等等。在這種情況下,枚舉更好(如果你不知道它們是什麼,不用擔心,只需給每個狀態一個有意義的名字和一個唯一的數字)。一旦完成,修改BlinkWithoutDelay,以便每次進入if時間已過, – frarugi87

+0

執行正確的操作並且狀態是高級的(例如,如果當前狀態爲state_green_on,則必須爲1 )將當前狀態設置爲state_green_off_yellow_on; 2)將綠燈關閉; 3)將黃色指示燈亮起。對所有的州都這樣做,並且你將有一個不會阻止和執行所有事情的程序。我建議你避免使用有限狀態機庫,因爲在我看來,你必須在使用準備使用的代碼之前學習FSM的基本知識和限制(你的例子是可以實現的FSM的最微不足道的例子很容易) – frarugi87

+0

請不要在標題中加上「[FIXED]」或「[已解決]」,請不要在問題的正文中加入答案。表明你的問題已經解決的方法是接受一個答案。發佈並接受你自己的答案是完全可以接受的。 –

回答

0

我試圖用Blinkwithoutdelay但作爲一個新手,它非常複雜 我使用它。

你必須更加努力:)

想象環路()是不是「程序」,但任何時候的描述。 一般而言,它會檢測到既沒有更改時間也沒有新的按鈕請求,所以循環立即退出。 即使發生了什麼事情,任何新的反應都不需要任何時間,循環立即退出。

+0

嗨,謝謝我已經修復它 –

0

有一個簡單的解決方案來解決給定的交通燈樣本。

int globalFlagSomeonePressedBeam = false; // store global if someone pushed the beam button 

void delay_and_check_for_beam (int msDelay) { 
    for (int i=0; i<msDelay; ++i) { 
     if(digitalRead(beam)==HIGH){ // check beam button 
      globalFlagSomeonePressedBeam = true; // store information 
     } 
     delay(1); 
    } 
} 

呼叫您設置的右燈(數字奏) 後您檢查globalFlagSomeonePressedBeam您需要延時功能之間:

與其說你可以打電話給你的特殊延遲功能延遲功能將其設置爲假