2016-11-07 3 views
0

Я пытаюсь запустить программу в Arduino Uno, где уличный свет, который имеет 3 цвета, красный, желтый и зеленый, и когда я нажимаю кнопку, уличный свет переходит от зеленого в желтый к красный, а затем свет пешеходной улицы переходит от красного к зеленому, как обычный уличный фонарь. Проблема в том, что моя программа не читает мою кнопку, когда она нажата по какой-то причине, я подумал, что это может быть protoboard или Arduino, но когда я пытаюсь запустить ее на схемах. Результат такой же, что приводит меня к выводу, что мой код - это не так. Так вот:Arduino street light with button 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 библиотеку Timer

И это фактический код:

// 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 для кнопки - плохая идея. ISR с Arduino - это нечто иное, чем то, что вы, очевидно, думаете – datafiddler

ответ

1

Вы подключаете прерывание к цифровому выводу 0, который, похоже, не подключен ни к чему, основанный на исходном коде, который вы показываете. Также в вашей процедуре обслуживания прерываний вы читаете кнопку в переменной buttonState, но вы не получаете доступ к этой переменной в другом месте кода.

+0

attachInterrupt и Pin-Number немного сложны. Pin 2 и attachInterrupt (0, func, RISING) идут вместе на Arduino UNO, например. – datafiddler