0

赤、黄、緑の3色の街灯が点灯するプログラムをArduino Unoで実行しようとしています。ボタンを押すと、街路灯が緑から黄色、赤に変わり、歩行者街灯が通常の街路灯と同じように、赤から緑に変わります。問題は、何らかの理由でボタンを押したときにプログラムがボタンを読み取らないことです。おそらくプロトタイプボードまたはArduinoであると思いましたが、回路で実行しようとすると結果は同じであり、私の結論に至りましたコードが間違っています。だからここにあります:

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

circuit.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);
}
4

1 に答える 1

1

割り込みをデジタルピン 0 に接続していますが、表示されているソースコードに基づいて何にも接続されていないようです。また、割り込みサービス ルーチンでは、ボタンを変数 buttonState に読み込みますが、コード内の他の場所でその変数にアクセスすることはありません。

于 2016-11-08T02:58:38.540 に答える