gpt4 book ai didi

audio - Arduino - 带 PWM 的蜂鸣器

转载 作者:行者123 更新时间:2023-12-02 22:37:01 29 4
gpt4 key购买 nike

我正在尝试用蜂鸣器和 Arduino 制作和弦音乐播放器。我在关注 this教程作为指南,但我无法弄清楚。代码就像:

void playTone() {
long elapsed_time = 0;
if (tone_ > 0) { // if this isn't a Rest beat, while the tone has
// played less long than 'duration', pulse speaker HIGH and LOW
while (elapsed_time < duration) {

digitalWrite(speakerOut, HIGH);
delayMicroseconds(tone_ / 2);

// DOWN
digitalWrite(speakerOut, LOW);
delayMicroseconds(tone_ / 2);

// Keep track of how long we pulsed
elapsed_time += (tone_);
}
}
else { // Rest beat; loop times delay
for (int j = 0; j < rest_count; j++) { // See NOTE on rest_count
delayMicroseconds(duration);
}
}
}

void loop() {
// Set up a counter to pull from melody[] and beats[]
for (int i = 0; i<MAX_COUNT; i++) {
tone_ = melody[i];
beat = beats[i];

duration = beat * tempo; // Set up timing

playTone();
// A pause between notes...
delayMicroseconds(pause);

}
}

我被困在“digitalWrite(speakerOut,HIGH);”线。好的,在我调用 playTone 函数之前,我设置了“tone_ = melody[i];”但是在函数中我们只在延迟函数中使用它。

我的问题是它是如何跟随旋律排列的?基于此,我将再添加一个蜂鸣器并由另一个阵列控制它,但现在我无能为力......

最佳答案

我看到你的困惑,因为你的程序被阻塞(只是循环延迟)你不能并行添加更多的旋律。解决方案是将代码重写为 非阻塞 接口(interface)使用定时器/计数器 和迭代过程。为简单起见,我们假设简单的数字 1 位声音。为了确保后者的复音,我们需要有 PWM,以便我们可以将更多 channel 添加在一起。

  • 让我们从单音开始

    对于每个声道,您需要存储实际状态,例如:
  • 音段T [T] 其中T = ftimer/ftone
  • 音调 PWM 周期中的实际时间 t [T] 其中0 <= t <= T
  • 音幅A [-] 或音量应为 A <= T/2
  • 扬声器状态 on (开/关)

  • 其中 [T] 表示某个计时器/计数器的周期,它将通过(采样率)将所有值转换为整数来更新。现在你只需创建一些 update该函数将从某个定时器以足够高的频率定期调用,并将决定扬声器的状态(开/关)。

    mono tone
  • 旋律

    只需添加一些计数器 n [T] 表示当前音调应该播放多少个周期。在 update减少它,如果它达到零,从你的旋律表中获取新的音调。因此,您还需要添加一些索引,您的旋律中当前正在播放哪个音调。
  • 复调

    好吧,您可以通过 HW 通过线或连接更多数字引脚(每个 channel 一个)来实现它。但这也可以通过 SW 方式实现。只需通过 on 将每个 channel 逻辑地添加在一起每个值应该 channel 在一起并通过其结果(A|B)设置扬声器。那工作,但输出质量不是很好。更好的是使用算术加法(A+B)并将结果用作输出的 PWM,该输出具有用于音调合成的采样频率的一些倍数。

    polyphony

    您也可以使用 DAC 代替 PWM ...

  • 我不为 ARDUINO 编码,所以我不能分享完整的代码。但是在我的 AVR32 上,C/C++ 代码如下所示:

    //---------------------------------------------------------------------------
    #ifndef _music_h
    #define _music_h
    //---------------------------------------------------------------------------
    #ifdef VCL_H
    #define U8 BYTE
    #define U16 WORD
    #define U32 DWORD
    #endif
    //---------------------------------------------------------------------------
    //#define _music_shifted_notes
    //---------------------------------------------------------------------------
    // volume
    #define music_A 5
    // max channels
    #define music_sys_T 3
    // _music update freq
    #define music_f ftim0/music_sys_T
    //---------------------------------------------------------------------------
    // music frequency 100*f [Hz], C_0 means C#0, P means pause
    //---------------------------------------------------------------------------
    #define P 0

    #ifdef _music_shifted_notes
    // musics data shifted frequencies C4 -> C1
    #define C1 26163
    #define C_1 27718
    #define D1 29366
    #define D_1 31113
    #define E1 32963
    #define F1 34923
    #define F_1 36999
    #define G1 39200
    #define G_1 41530
    #define A1 44000
    #define A_1 46616
    #define B1 49388

    #define C2 52325
    #define C_2 55437
    #define D2 58733
    #define D_2 62225
    #define E2 65925
    #define F2 69846
    #define F_2 73999
    #define G2 78399
    #define G_2 83061
    #define A2 88000
    #define A_2 93233
    #define B2 98777

    #define C3 104650
    #define C_3 110873
    #define D3 117466
    #define D_3 124451
    #define E3 131851
    #define F3 139691
    #define F_3 147998
    #define G3 156798
    #define G_3 166122
    #define A3 176000
    #define A_3 186466
    #define B3 197553

    #define C4 209300
    #define C_4 221746
    #define D4 234932
    #define D_4 248902
    #define E4 263702
    #define F4 279383
    #define F_4 295996
    #define G4 313596
    #define G_4 332244
    #define A4 352000
    #define A_4 372931
    #define B4 395107
    #else
    // real note frequuencies
    #define C0 1635
    #define C_0 1732
    #define D0 1835
    #define D_0 1945
    #define E0 2060
    #define F0 2183
    #define F_0 2312
    #define G0 2450
    #define G_0 2596
    #define A0 2750
    #define A_0 2914
    #define B0 3087

    #define C1 3270
    #define C_1 3465
    #define D1 3671
    #define D_1 3889
    #define E1 4120
    #define F1 4365
    #define F_1 4625
    #define G1 4900
    #define G_1 5191
    #define A1 5500
    #define A_1 5827
    #define B1 6174

    #define C2 6541
    #define C_2 6930
    #define D2 7342
    #define D_2 7778
    #define E2 8241
    #define F2 8731
    #define F_2 9250
    #define G2 9800
    #define G_2 10383
    #define A2 11000
    #define A_2 11654
    #define B2 12347

    #define C3 13081
    #define C_3 13859
    #define D3 14683
    #define D_3 15556
    #define E3 16481
    #define F3 17461
    #define F_3 18500
    #define G3 19600
    #define G_3 20765
    #define A3 22000
    #define A_3 23308
    #define B3 24694

    #define C4 26163
    #define C_4 27718
    #define D4 29366
    #define D_4 31113
    #define E4 32963
    #define F4 34923
    #define F_4 36999
    #define G4 39200
    #define G_4 41530
    #define A4 44000
    #define A_4 46616
    #define B4 49388

    #define C5 52325
    #define C_5 55437
    #define D5 58733
    #define D_5 62225
    #define E5 65925
    #define F5 69846
    #define F_5 73999
    #define G5 78399
    #define G_5 83061
    #define A5 88000
    #define A_5 93233
    #define B5 98777

    #define C6 104650
    #define C_6 110873
    #define D6 117466
    #define D_6 124451
    #define E6 131851
    #define F6 139691
    #define F_6 147998
    #define G6 156798
    #define G_6 166122
    #define A6 176000
    #define A_6 186466
    #define B6 197553

    #define C7 209300
    #define C_7 221746
    #define D7 234932
    #define D_7 248902
    #define E7 263702
    #define F7 279383
    #define F_7 295996
    #define G7 313596
    #define G_7 332244
    #define A7 352000
    #define A_7 372931
    #define B7 395107

    #define C8 418601
    #define C_8 443492
    #define D8 469863
    #define D_8 497803
    #define E8 527404
    #define F8 558765
    #define F_8 591991
    #define G8 627193
    #define G_8 664488
    #define A8 704000
    #define A_8 745862
    #define B8 790213
    #endif

    #define H0 B0
    #define H1 B1
    #define H2 B2
    #define H3 B3
    #define H4 B4
    #define H5 B5
    #define H6 B6
    #define H7 B7
    #define H8 B8
    #define H_0 B_0
    #define H_1 B_1
    #define H_2 B_2
    #define H_3 B_3
    #define H_4 B_4
    #define H_5 B_5
    #define H_6 B_6
    #define H_7 B_7
    #define H_8 B_8
    //---------------------------------------------------------------------------
    // music tempo delays [ms]
    //---------------------------------------------------------------------------
    #define T32 62
    #define T20 100
    #define T16 125
    #define T10 200
    #define T9 222
    #define T8 250
    #define T7 285
    #define T6 333
    #define T5 400
    #define T4 500
    #define T3 666
    #define T2 1000
    #define T1 2000
    //---------------------------------------------------------------------------
    typedef struct
    {
    U32 T,t,n,on;
    U32 *melody;
    } _music;
    //---------------------------------------------------------------------------
    void music_play(_music *m,U32 *melody)
    {
    m->melody=melody;
    m->t=0;
    m->T=0;
    m->on=0;
    m->n=1;
    }
    //---------------------------------------------------------------------------
    void music_stop(_music *m)
    {
    m->melody=NULL;
    m->t=0;
    m->T=0;
    m->on=0;
    m->n=1;
    }
    //---------------------------------------------------------------------------
    void music_update(_music *m)
    {
    if (m->melody==NULL) { m->on=0; return; }
    m->n--; if (!m->n)
    {
    U32 x;
    m->T=m->melody[0]; m->melody++;
    if (m->T) m->T=(100*music_f)/m->T;
    if (m->melody==NULL) { m->on=0; return; }
    m->n=(m->melody[0]*music_f)/1000; m->melody++;
    m->on=1; m->t=0;
    if (m->n==0) m->melody=NULL;
    }
    m->t++; if (m->t==m->T){ m->on=1; m->t=0; }
    if (m->t==music_A) m->on=0;
    }
    //---------------------------------------------------------------------------
    void music_sys_init(_music *m,int n)
    {
    for (int i=0;i<n;i++) music_stop(m+i);
    }
    //---------------------------------------------------------------------------
    void music_sys_update(_music *m,int n,U32 pin)
    {
    static U32 t=0,A=0;
    int i;
    t++;
    if (t==music_sys_T)
    {
    t=0; A=0;
    for (i=0;i<n;i++)
    {
    music_update(m+i);
    if (m[i].on) A++;
    }
    if (A) gpio_set_gpio_pin(pin);
    }
    if (t==A) gpio_clr_gpio_pin(pin);
    }
    //---------------------------------------------------------------------------
    #endif
    //---------------------------------------------------------------------------

    所以我只有一些 _music 的数组代表我所有的 channel 并调用 music_sys_update在某些定时器中为他们提供频率 ftim0我正在使用 ftim0=200000 [赫兹]。

    #include "music.h"
    #define music_channels 2
    volatile _music music[music_channels];

    const U32 music_data[]= // melody (frequency [0.01*Hz],duration [ms])
    {
    C5 ,400,D5 ,400,E5 ,400,C5 ,400,
    C5 ,400,D5 ,400,E5 ,400,C5 ,400,
    E5 ,400,F5 ,400,G5 ,800,E5 ,400,F5 ,400,G5 ,800,
    G5 ,200,A5 ,200,G5 ,200,F5 ,200,E5 ,400,C5 ,400,
    G5 ,200,A5 ,200,G5 ,200,F5 ,200,E5 ,400,C5 ,400,
    C5 ,400,G4 ,400,C5 ,800,
    C5 ,400,G4 ,400,C5 ,800,
    0,0, // end of melody
    };

    // this do once for init
    music_sys_init(music,music_channels);
    // this starts playback on channel 0
    music_play(&music[0],music_data);

    // this should be inside timer but also blocking loop like this would do:
    for (;;)
    {
    music_sys_update(music,music_channels,sound_pin);
    wait 1000000/ftim0 [us]
    }

    所以只需将其移植到您的环境中并玩得开心:) ...

    关于audio - Arduino - 带 PWM 的蜂鸣器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49545881/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com