2016-11-07 83 views
0

我想在Arduino Uno中運行一個程序,其中有3種顏色,紅色,黃色和綠色的路燈,當我按下按鈕時,路燈從綠色變爲黃色,紅色,然後步行街燈從紅色變成綠色,就像普通的路燈一樣。問題是我的程序因爲某種原因沒有按下我的按鈕,我認爲它可能是protoboard或Arduino,但是當我嘗試在circuits.io上運行它時,結果是一樣的,導致我得出結論,即我的代碼是什麼錯誤。所以在這裏,它是:Arduino路燈與按鈕attachInterrupt

//libreria 
#define EVENT_NONE 0 
#define EVENT_EVERY 1 
#define EVENT_OSCILLATE 2 
#define MAX_NUMBER_OF_EVENTS (10) 

#define TIMER_NOT_AN_EVENT (-2) 
#define NO_TIMER_AVAILABLE (-1) 
class Event { 
public: 
    Event(void); 
    void update(void); 
    void update(unsigned long now); 
    int8_t eventType; 
    unsigned long period; 
    int repeatCount; 
    uint8_t pin; 
    uint8_t pinState; 
    void (*callback)(void); 
    unsigned long lastEventTime; 
    int count; 
}; 

Event::Event(void) 
{ 
    eventType = EVENT_NONE; 
} 

void Event::update(void) 
{ 
    unsigned long now = millis(); 
    update(now); 
} 

void Event::update(unsigned long now) 
{ 
    if (now - lastEventTime >= period) { 
     switch (eventType) { 
     case EVENT_EVERY: 
      (*callback)(); 
      break; 

     case EVENT_OSCILLATE: 
      pinState = !pinState; 
      digitalWrite(pin, pinState); 
      break; 
     } 
     lastEventTime = now; 
     count++; 
    } 
    if (repeatCount > -1 && count >= repeatCount) { 
     eventType = EVENT_NONE; 
    } 
} 
//libreria timer 

class Timer { 

public: 
    Timer(void); 

    int8_t every(unsigned long period, void (*callback)(void)); 
    int8_t every(unsigned long period, void (*callback)(void), int repeatCount); 
    int8_t after(unsigned long duration, void (*callback)(void)); 
    int8_t oscillate(uint8_t pin, unsigned long period, uint8_t startingValue); 
    int8_t oscillate(uint8_t pin, unsigned long period, uint8_t startingValue, int repeatCount); 

    /** 
     * This method will generate a pulse of !startingValue, occuring period after the 
     * call of this method and lasting for period. The Pin will be left in !startingValue. 
     */ 
    int8_t pulse(uint8_t pin, unsigned long period, uint8_t startingValue); 

    /** 
     * This method will generate a pulse of pulseValue, starting immediately and of 
     * length period. The pin will be left in the !pulseValue state 
     */ 
    int8_t pulseImmediate(uint8_t pin, unsigned long period, uint8_t pulseValue); 
    void stop(int8_t id); 
    void update(void); 
    void update(unsigned long now); 

protected: 
    Event _events[MAX_NUMBER_OF_EVENTS]; 
    int8_t findFreeEventIndex(void); 
}; 

Timer::Timer(void) 
{ 
} 

int8_t Timer::every(unsigned long period, void (*callback)(), int repeatCount) 
{ 
    int8_t i = findFreeEventIndex(); 
    if (i == -1) 
     return -1; 

    _events[i].eventType = EVENT_EVERY; 
    _events[i].period = period; 
    _events[i].repeatCount = repeatCount; 
    _events[i].callback = callback; 
    _events[i].lastEventTime = millis(); 
    _events[i].count = 0; 
    return i; 
} 

int8_t Timer::every(unsigned long period, void (*callback)()) 
{ 
    return every(period, callback, -1); // - means forever 
} 

int8_t Timer::after(unsigned long period, void (*callback)()) 
{ 
    return every(period, callback, 1); 
} 

int8_t Timer::oscillate(uint8_t pin, unsigned long period, uint8_t startingValue, int repeatCount) 
{ 
    int8_t i = findFreeEventIndex(); 
    if (i == NO_TIMER_AVAILABLE) 
     return NO_TIMER_AVAILABLE; 

    _events[i].eventType = EVENT_OSCILLATE; 
    _events[i].pin = pin; 
    _events[i].period = period; 
    _events[i].pinState = startingValue; 
    digitalWrite(pin, startingValue); 
    _events[i].repeatCount = repeatCount * 2; // full cycles not transitions 
    _events[i].lastEventTime = millis(); 
    _events[i].count = 0; 
    return i; 
} 

int8_t Timer::oscillate(uint8_t pin, unsigned long period, uint8_t startingValue) 
{ 
    return oscillate(pin, period, startingValue, -1); // forever 
} 

/** 
    * This method will generate a pulse of !startingValue, occuring period after the 
    * call of this method and lasting for period. The Pin will be left in !startingValue. 
    */ 
int8_t Timer::pulse(uint8_t pin, unsigned long period, uint8_t startingValue) 
{ 
    return oscillate(pin, period, startingValue, 1); // once 
} 

/** 
    * This method will generate a pulse of startingValue, starting immediately and of 
    * length period. The pin will be left in the !startingValue state 
    */ 
int8_t Timer::pulseImmediate(uint8_t pin, unsigned long period, uint8_t pulseValue) 
{ 
    int8_t id(oscillate(pin, period, pulseValue, 1)); 
    // now fix the repeat count 
    if (id >= 0 && id < MAX_NUMBER_OF_EVENTS) { 
     _events[id].repeatCount = 1; 
    } 
    return id; 
} 

void Timer::stop(int8_t id) 
{ 
    if (id >= 0 && id < MAX_NUMBER_OF_EVENTS) { 
     _events[id].eventType = EVENT_NONE; 
    } 
} 

void Timer::update(void) 
{ 
    unsigned long now = millis(); 
    update(now); 
} 

void Timer::update(unsigned long now) 
{ 
    for (int8_t i = 0; i < MAX_NUMBER_OF_EVENTS; i++) { 
     if (_events[i].eventType != EVENT_NONE) { 
      _events[i].update(now); 
     } 
    } 
} 
int8_t Timer::findFreeEventIndex(void) 
{ 
    for (int8_t i = 0; i < MAX_NUMBER_OF_EVENTS; i++) { 
     if (_events[i].eventType == EVENT_NONE) { 
      return i; 
     } 
    } 
    return NO_TIMER_AVAILABLE; 
} 

此代碼只是一個導入庫,因爲circuits.io不能使用的#include定時器庫

方式,這是實際的代碼:

// Street Light Code 

int redCar = 12; 
int yellowCar = 11; 
int greenCar = 10; 
int redWalk = 9; 
int greenWalk = 8; 
const int button = 2; 
unsigned long lightChange = 1000; 
volatile int buttonState = 0; 
Timer t; 

void setup() { 
    pinMode(redCar, OUTPUT); 
    pinMode(yellowCar, OUTPUT); 
    pinMode(greenCar, OUTPUT); 
    pinMode(redWalk, OUTPUT); 
    pinMode(greenWalk, OUTPUT); 
    pinMode(button, INPUT); 
    attachInterrupt(0, interrupcion, RISING); 
    digitalWrite(greenCar, HIGH); 
    digitalWrite(redWalk, HIGH); 
} 

void loop() { 
    t.update(); 
} 

void interrupcion() { 
    buttonState = digitalRead(button); 
    start(); 
} 

void start() { 
    digitalWrite(greenCar, HIGH); 
    digitalWrite(yellowCar, LOW); 
    digitalWrite(redCar, LOW); 
    digitalWrite(greenWalk, LOW); 
    digitalWrite(redWalk, HIGH); 
    t.after(lightChange, green_light_car); 
} 

void green_light_car() { 
    t.oscillate(greenCar, 50, LOW, 10); 
    digitalWrite(yellowCar, LOW); 
    digitalWrite(redCar, LOW); 
    digitalWrite(greenWalk, LOW); 
    digitalWrite(redWalk, HIGH); 
    t.after(lightChange, yellow_light_car); 
} 

void yellow_light_car() { 
    digitalWrite(greenCar, LOW); 
    digitalWrite(yellowCar, HIGH); 
    digitalWrite(redCar, LOW); 
    digitalWrite(greenWalk, LOW); 
    digitalWrite(redWalk, HIGH); 
    t.after(lightChange, red_light_car); 
} 

void red_light_car() { 
    digitalWrite(greenCar, LOW); 
    digitalWrite(yellowCar, LOW); 
    digitalWrite(redCar, HIGH); 
    digitalWrite(greenWalk, HIGH); 
    digitalWrite(redWalk, LOW); 
    t.after(lightChange, green_light_walk); 
} 

void green_light_walk() { 
    digitalWrite(greenCar, LOW); 
    digitalWrite(yellowCar, LOW); 
    digitalWrite(redCar, HIGH); 
    t.oscillate(greenWalk, 50, LOW, 10); 
    digitalWrite(redWalk, LOW); 
    t.after(lightChange, red_light_walk); 
} 

void red_light_walk() { 
    digitalWrite(greenCar, HIGH); 
    digitalWrite(yellowCar, LOW); 
    digitalWrite(redCar, LOW); 
    digitalWrite(greenWalk, LOW); 
    digitalWrite(redWalk, HIGH); 
    t.after(lightChange, interrupcion); 
} 
+0

t.after(...)在ISR中不是一個好主意。無論如何,一個按鈕的ISR是一個壞主意。帶有Arduino的ISR與你明顯想象的不同 – datafiddler

回答

1

您正在將中斷附加到數字引腳0,該引腳似乎根據所顯示的源代碼而沒有連接任何內容。同樣在你的中斷服務程序中,你將按鈕讀入變量buttonState,但是你不能在代碼中的任何其他位置訪問該變量。

+0

attachInterrupt和Pin-Number有點複雜Pin 2和attachInterrupt(0,func,RISING)在Arduino UNO上一起使用 – datafiddler