Arduino路灯带按钮attachInterrupt

时间:2016-11-07 23:20:24

标签: button arduino interruption interruptions

我正在尝试在Arduino Uno中运行一个程序,其中有3种颜色的红色,黄色和绿色的路灯,当我按下按钮时,路灯从绿色变为黄色到红色然后是步行街光线从红色变为绿色,就像普通的路灯一样。问题是我的程序因为某些原因被按下时没有读取我的按钮,我认为它可能是原型板或Arduino但是当我尝试在circuit.io上运行时,结果是一样的,导致我我的代码是错误的结论。所以这就是:

//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);
}

1 个答案:

答案 0 :(得分:1)

您正在将中断附加到数字引脚0,根据您显示的源代码,它似乎没有连接到任何内容。同样在你的中断服务程序中,你将按钮读入变量buttonState,但你不能在代码中的任何其他位置访问该变量。