为什么我的按钮按下功能不会被声明到我附加的中断中?

Why is wont my button pressed functions be declared to my attached interrupts?

提问人:Eclipse 提问时间:11/17/2023 最后编辑:Eclipse 更新时间:11/18/2023 访问量:31

问:

我正在使用 Arduino 为我的学校项目制作一个反应游戏,我想使用附加中断来注册我的按钮按下,但我所做的功能不会在我尝试制作的附加中断语句中声明。这也是我第一次使用基于对象的编程,所以我并不完全习惯它的工作原理。

#include <Arduino.h>
// Game class
/**
 * The Game class represents a reaction game that can be played between two players.
 * 
 * The game starts when any button is pressed. The RGB LED will turn red for a random
 * amount of time, and then turn green. The first player to press their button when the
 * RGB LED turns green will win the round. The winner's indicator LED and the RGB LED will
 * flash rapidly several times, and a fanfare will play from the buzzer. If a player presses
 * their button before the RGB LED turns green, they will lose the round and their indicator
 * LED and the RGB LED will flash rapidly several times, and a failure sound will play from
 * the buzzer. The class takes in the pin numbers for the buttons, LEDs, RGB LED, and buzzer
 * as parameters in the constructor. The class provides methods to start the game, blink the
 * winner LED, blink the RGB LED, and randomize the lights.
 */
class Game {
  private:
    bool started; // Whether the game has started
    bool over; // Whether the game is over
    int winner; // The winner of the game (1 or 2)
    int reactionTime; // The reaction time of the winner
    unsigned long startTime; // The start time of the game
    int button1Pin;
    int button2Pin;
    int led1Pin;
    int led2Pin;
    int redPin;
    int greenPin;
    int bluePin;
    int buzzerPin;
    int player1Score;
    int player2Score;
  public:
    Game(int b1, int b2, int l1, int l2, int r, int g, int b, int bz) {
      button1Pin = b1;
      button2Pin = b2;
      led1Pin = l1;
      led2Pin = l2;
      redPin = r;
      greenPin = g;
      bluePin = b;
      buzzerPin = bz;
      started = false;
      over = false;
      winner = 0;
      reactionTime = 0;
      player1Score = 0;
      player2Score = 0;
      pinMode(button1Pin, INPUT_PULLUP);
      pinMode(button2Pin, INPUT_PULLUP);
      pinMode(led1Pin, OUTPUT);
      pinMode(led2Pin, OUTPUT);
      pinMode(redPin, OUTPUT);
      pinMode(greenPin, OUTPUT);
      pinMode(bluePin, OUTPUT);
      pinMode(buzzerPin, OUTPUT);
      attachInterrupt(digitalPinToInterrupt(button1Pin), button1Pressed, FALLING);
      attachInterrupt(digitalPinToInterrupt(button2Pin), button2Pressed, FALLING);
    }
    void start() {
      Serial.println("Press any button to start the game");
      while (!digitalRead(button1Pin) && !digitalRead(button2Pin)) {
        // Wait for button press
      }
      started = true;
      Serial.println("Game started!");
    }
    void blinkWinnerLed() {
      if (over) {
        if (winner == 1) {
          digitalWrite(led1Pin, HIGH);
          delay(100);
          digitalWrite(led1Pin, LOW);
          digitalWrite(redPin, LOW);
          digitalWrite(greenPin, LOW);
          digitalWrite(bluePin, LOW);
          for (int i = 0; i < 5; i++) {
            digitalWrite(led1Pin, HIGH);
            digitalWrite(greenPin, HIGH);
            digitalWrite(bluePin, HIGH);
            delay(100);
            digitalWrite(led1Pin, LOW);
            digitalWrite(greenPin, LOW);
            digitalWrite(bluePin, LOW);
            delay(100);
          }
        } else if (winner == 2) {
          digitalWrite(led2Pin, HIGH);
          delay(100);
          digitalWrite(led2Pin, LOW);
          digitalWrite(redPin, LOW);
          digitalWrite(greenPin, LOW);
          digitalWrite(bluePin, LOW);
          for (int i = 0; i < 5; i++) {
            digitalWrite(led2Pin, HIGH);
            digitalWrite(greenPin, HIGH);
            digitalWrite(bluePin, HIGH);
            delay(100);
            digitalWrite(led2Pin, LOW);
            digitalWrite(greenPin, LOW);
            digitalWrite(bluePin, LOW);
            delay(100);
          }
        }
      }
    }
    void button1Pressed() {
      if (!over && started) {
        over = true;
        winner = 1;
        reactionTime = millis() - startTime;
        digitalWrite(led1Pin, HIGH);
        digitalWrite(redPin, LOW);
        digitalWrite(greenPin, HIGH);
        digitalWrite(bluePin, LOW);
        tone(buzzerPin, 440, 500);
        Serial.println("Player 1 wins!");
        Serial.print("Reaction time: ");
        Serial.print(reactionTime);
        Serial.println("ms");
        player1Score++;
        delay(2000);
        resetGame();
      }
    }
    void button2Pressed() {
      if (!over && started) {
        over = true;
        winner = 2;
        reactionTime = millis() - startTime;
        digitalWrite(led2Pin, HIGH);
        digitalWrite(redPin, LOW);
        digitalWrite(greenPin, HIGH);
        digitalWrite(bluePin, LOW);
        tone(buzzerPin, 440, 500);
        Serial.println("Player 2 wins!");
        Serial.print("Reaction time: ");
        Serial.print(reactionTime);
        Serial.println("ms");
        player2Score++;
        delay(2000);
        resetGame();
      }
    }
    void blinkRgbLed() {
      if (started && !over) {
        int randomTime = random(3000, 6000);
        digitalWrite(redPin, HIGH);
        digitalWrite(greenPin, LOW);
        digitalWrite(bluePin, LOW);
        delay(randomTime);
        digitalWrite(redPin, LOW);
        digitalWrite(greenPin, HIGH);
        digitalWrite(bluePin, LOW);
        startTime = millis();
      }
      if (over) {
        if (winner == 1) {
          digitalWrite(redPin, LOW);
          digitalWrite(greenPin, HIGH);
          digitalWrite(bluePin, LOW);
        } else if (winner == 2) {
          digitalWrite(redPin, LOW);
          digitalWrite(greenPin, HIGH);
          digitalWrite(bluePin, LOW);
        } else {
          digitalWrite(redPin, LOW);
          digitalWrite(greenPin, LOW);
          digitalWrite(bluePin, HIGH);
        }
      }
    }
    void resetGame() {
      digitalWrite(led1Pin, LOW);
      digitalWrite(led2Pin, LOW);
      digitalWrite(redPin, LOW);
      digitalWrite(greenPin, LOW);
      digitalWrite(bluePin, LOW);
      over = false;
      winner = 0;
      reactionTime = 0;
      startTime = 0;
    }
    int getPlayer1Score() {
      return player1Score;
    }
    int getPlayer2Score() {
      return player2Score;
    }
};

// Create a Game object with the specified pins
Game game(2, 3, 6, 7, 9, 10, 11, 12);


void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(0));
  game.start();
  delay(250); // Add a 250ms delay after the game starts
}

void loop() {
  game.blinkWinnerLed();
  game.blinkRgbLed();
}

我试图在代码周围移动函数以声明主题,但无论我把它们放在哪里,它们都会导致我的整个代码出现错误。我非常有信心这是因为附加中断在类中,但我不知道如何使它适合我的其余代码。

Arduino 语法错误 Arduino-uno

评论

0赞 Delta_G 11/17/2023
“不会被宣布”是什么意思?是否有错误消息?如果是这样,请将其发布在您的问题中。
0赞 Juraj 11/17/2023
添加 forward 声明或将函数移到 setup() 上方。这是Arduino builder的问题。arduino.stackexchange.com/questions/73234/......

答:

0赞 hcheung 11/17/2023 #1

你从来没有清楚地提到你得到的确切错误,但我建议阅读 在类中调用中断

除了 Juraj 提到的关于远期申报的内容。关于类的设计存在一些问题。

当Arduino启动时,它有一个main()函数,该函数在将控件传递给之前进行系统初始化(例如定义引脚,设置电路板变体等)。您的类结构被实例化并尝试在调用 main() 之前运行代码,而 Arduino 还不知道如何执行这些代码。这就是为什么几乎所有的Arduino库都有一个方法,你的类结构应该只包含类变量初始化,在被调用之前,不应该在类结构中运行任何代码。重新设计类结构,将 setting 和 interrupt 等代码移动到方法中,然后在 .您当前的实现可能取决于编译器处理它的方式,但不能保证。setup()init()begin()setup()pinMode()begin()setup()

其他参考资料:

为 Arduino 编写库

Arduino API 风格指南

中断处理程序 and 是 way to long,它应该保持尽可能短,并且不应包含阻塞函数,例如 和 .我建议阅读尼克·金蒙(Nick Gammon)的《中断》(Interrupt)。button1Pressed()button2Pressed()delay()tone()Serial.print()