我正在尝试在 Arduino Uno 中运行一个程序,其中的路灯有 3 种颜色,红色、黄色和绿色,当我按下按钮时,路灯从绿色变为黄色再变为红色,然后步行街灯从红色到绿色,就像普通的路灯一样。问题是我的程序由于某种原因被按下时没有读取我的按钮,我认为它可能是 protoboard 或 Arduino 但是当我尝试在circuits.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);
}