用Arduino播放音乐

时间:2017-03-08 19:08:15

标签: arduino speaker

我尝试编写一首用Arduino播放的小歌曲,其中有6个扬声器。这个过程应该是我打开频率上不同的扬声器并倒计时音符的持续时间。如果持续时间结束,我会播放下一个声音或转动扬声器。我为6个扬声器定义了不同的阵列。此外,我还有很多关于音符频率和持续时间的定义。

问题是,我只是深深的哼唱而不是曲调。

有没有人建议代码可能有什么问题?

#define pause 0
#define c1    32.7
#define cis1  34.6
#define d1    36.7
#define dis1  38.9
...

#define l1 32
#define l2 16
...

#define note 0
#define laenge 1

int myChannels[] = { 8, 9, 10, 11, 12, 13 };
int myDuration[] = { 0, 0, 0,  0,  0,  0 };
int myPointer[] =  { 0, 0, 0,  0,  0,  0 };
const PROGMEM float myPlayList[6][600][2] = {
   // 1st Voice
   {
     { c2, l8}, { g2, l8}, { c2, l8}, { g2, l8}, { c2, l8}, { g2, l8}, { c2, l8}, { g2, l8},
     { c2, l8}, { g2, l8}, { c2, l8}, { g2, l8}, { c2, l8}, { g2, l8}, { c2, l8}, { g2, 18},
     ...
   }
};

void play( int out, float freq, float len) {
  if (freq > 0) {
    tone ( myChannels[out], freq);
  } else {
    noTone ( freq);
  }
  myDuration[ out] = len;
}

void setup() {
  for ( int channel = 0; channel < 6; channel++) {
    pinMode (myChannels[channel], OUTPUT);
  }
}

void loop() {
  boolean playing = false;

  for ( int channel = 0; channel < 6; channel++) {
    if (myDuration[channel] == 0) {
      if (myPointer[channel] < sizeof(myPlayList[channel])) {
        play( channel, myPlayList[channel][myPointer[channel]][0], myPlayList[channel][myPointer[channel]][1]);
        myPointer[channel]++;
        playing = true;
      } else {
        noTone ( channel);
      }
    } else {
      myDuration[channel]--;
      playing = true;
    }
  }

  if (!playing) {
    delay (10000);
    for ( int channel = 0; channel < 6; channel++) {
      myDuration[channel] = 0;
      myPointer[channel] = 0;
    }
  }

  delay (25);
}

1 个答案:

答案 0 :(得分:0)

您尝试同时为六个单独的频道调用tone()功能。这不起作用,因为arduino核心库的tone()函数被指定用于一次生成一个音调。原因是它使用单个硬件定时器来产生方波。

以下是关于如何实现您想要实现的目标的非详尽清单:

  1. 制作您的设计单音。一个针,一个扬声器,一个声音。
  2. 利用micros()手动生成正方形。
  3. 使用Brett Hagman的音调库:https://code.google.com/archive/p/rogue-code/wikis/ToneLibraryDocumentation.wiki#Ugly_Details。该库使用更多硬件定时器,实际数量取决于您的主板的Atmel芯片。请注意,您需要一个带有ATmega1280 +芯片的Arduino,以便能够同时驱动六个引脚。
  4. 在旁注中,tone()需要两个int作为参数。