【问题标题】:C++ buzzer to play piano notes for an Arduino为 Arduino 演奏钢琴音符的 C++ 蜂鸣器
【发布时间】:2017-08-11 10:07:21
【问题描述】:
unsigned long t;
boolean isHigh;

#define BUZZER_PIN 3

void setup() {
  // put your setup code here, to run once:
  pinMode(BUZZER_PIN, OUTPUT);
  isHigh = false;
  t = micros();
}

void loop() {
  playNote('c');
}

void playNote(char note) {
  unsigned long timeToWait;
  unsigned long timeToPlayTheNote = millis();
  while (timeToPlayTheNote - millis() < 1000) {
    if (note == 'c') {
      timeToWait = 1911;
    }
    if (micros() - t > timeToWait) {
      if (!isHigh) {
        digitalWrite(BUZZER_PIN, HIGH);
        isHigh = true;
      } else {
        digitalWrite(BUZZER_PIN, LOW);
        isHigh = false;
      }
      t = micros();
    }
  }
}

我不知道为什么这不起作用。我曾经每 1,000 微秒播放一次频率,但有什么方法可以让这更简单吗?此外,使用这种方法,我必须执行 (1/f)/2,然后将该值从秒转换为微秒,并将其用作 timeToWait 的值。

【问题讨论】:

  • 代码从不循环调用playNote函数,也不会注册为ISR
  • 它现在可以工作了,但无论如何我都需要为每个笔记添加很多 else if 语句来提高效率
  • 另一种方法是使用Timmer Interrupts 代替等待时间。
  • 一个更简单的方法是将切换BUZZER_PIN的逻辑替换为:digitalWrite(BUZZER_PIN, isHigh);isHigh=!isHigh;
  • 我的方法效率低吗?

标签: c++ arrays if-statement arduino


【解决方案1】:
  • ˋtimeToWait` 的初始化显然应该在循环之外。
  • 数组可用于计时数据。
  • ˋt`可能应该在ˋplayNoteˋ
  • 中初始化
  • 或者,您可以使用枚举来表示与音符相关的延迟。

    enum class notes
    {
        C = 1911
    };
    

好吧,所有建议都假设您不想补偿漂移偏移。

【讨论】:

    【解决方案2】:

    蜂鸣器的频率固定。它们根本不像扬声器那样工作。使用真正的扬声器,您将获得更好的效果。不要忘记串联一个电容器,以便扬声器看到交流信号,如果您输入直流信号,您可以很容易地炸毁扬声器。..

    为获得最佳效果,您应该背靠背使用 2 个 47uF 至 100uF 电解电容,负极连接在一起,一个正极连接到 'duino,另一个正极连接到扬声器。电容越大,低音就越多。

    为什么不使用 50% (128) 的 PWM 并更改 PWM 频率来产生声音?您可以为此使用 Timer1 或 Timer3 库。让硬件完成这项工作会更有压力,并且可以让您的应用程序腾出时间来完成其他任务,例如读取键盘。

    https://playground.arduino.cc/Code/Timer1

    使用 analogWrite() 将 PWM 设置为 0% 会切断声音。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-21
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      相关资源
      最近更新 更多