如何使音频和LED仅在使用Arduino按住按钮时激活?
我有一段代码,我用它来播放声音效果,我用一个叫wav2c的程序把一个.wav文件转换成数字值,我把它放进一个头文件,我在代码中用它来生成声音。目前,我已经将其编程为在上传到Arduino时播放音频,同时激活一个LED,并在音效期间保持点亮。我试图对其进行编程,使声音和LED仅在按下按钮时激活。我有按钮插入的pin码,但我不确定如何让它控制音频和LED,如上所述。我在编程或Arduino方面没有太多经验,因此非常感谢您的帮助!我用的是Arduino Mega 2560 代码如何使音频和LED仅在使用Arduino按住按钮时激活?,arduino,wav,Arduino,Wav,我有一段代码,我用它来播放声音效果,我用一个叫wav2c的程序把一个.wav文件转换成数字值,我把它放进一个头文件,我在代码中用它来生成声音。目前,我已经将其编程为在上传到Arduino时播放音频,同时激活一个LED,并在音效期间保持点亮。我试图对其进行编程,使声音和LED仅在按下按钮时激活。我有按钮插入的pin码,但我不确定如何让它控制音频和LED,如上所述。我在编程或Arduino方面没有太多经验,因此非常感谢您的帮助!我用的是Arduino Mega 2560 代码 #include &l
#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define SAMPLE_RATE 20000
#include "Test.h"
int ledPin = 2;
int speakerPin = 9; // Can be either 3 or 11, two PWM outputs connected to Timer 2
const byte pinSwitch1 = 3;
volatile uint16_t sample;
byte lastSample;
void stopPlayback()
{
digitalWrite(ledPin, LOW);
// Disable playback per-sample interrupt.
TIMSK1 &= ~_BV(OCIE1A);
// Disable the per-sample timer completely.
TCCR1B &= ~_BV(CS10);
// Disable the PWM timer.
TCCR2B &= ~_BV(CS10);
digitalWrite(speakerPin, LOW);
}
// This is called at 8000 Hz to load the next sample.
ISR(TIMER1_COMPA_vect) {
if (sample >= sounddata_length) {
if (sample == sounddata_length + lastSample) {
stopPlayback();
}
else {
if(speakerPin==11){
// Ramp down to zero to reduce the click at the end of playback.
OCR2A = sounddata_length + lastSample - sample;
} else {
OCR2B = sounddata_length + lastSample - sample;
}
}
}
else {
if(speakerPin==11){
OCR2A = pgm_read_byte(&sounddata_data[sample]);
} else {
OCR2B = pgm_read_byte(&sounddata_data[sample]);
}
}
++sample;
}
void startPlayback()
{
pinMode(speakerPin, OUTPUT);
// Set up Timer 2 to do pulse width modulation on the speaker
// pin.
// Use internal clock (datasheet p.160)
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
// Set fast PWM mode (p.157)
TCCR2A |= _BV(WGM21) | _BV(WGM20);
TCCR2B &= ~_BV(WGM22);
if(speakerPin==11){
// Do non-inverting PWM on pin OC2A (p.155)
// On the Arduino this is pin 11.
TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
// No prescaler (p.158)
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Set initial pulse width to the first sample.
OCR2A = pgm_read_byte(&sounddata_data[0]);
} else {
// Do non-inverting PWM on pin OC2B (p.155)
// On the Arduino this is pin 3.
TCCR2A = (TCCR2A | _BV(COM2B1)) & ~_BV(COM2B0);
TCCR2A &= ~(_BV(COM2A1) | _BV(COM2A0));
// No prescaler (p.158)
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Set initial pulse width to the first sample.
OCR2B = pgm_read_byte(&sounddata_data[0]);
}
// Set up Timer 1 to send a sample every interrupt.
cli();
// Set CTC mode (Clear Timer on Compare Match) (p.133)
// Have to set OCR1A *after*, otherwise it gets reset to 0!
TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
// No prescaler (p.134)
TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Set the compare register (OCR1A).
// OCR1A is a 16-bit register, so we have to do this with
// interrupts disabled to be safe.
OCR1A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
// Enable interrupt when TCNT1 == OCR1A (p.136)
TIMSK1 |= _BV(OCIE1A);
lastSample = pgm_read_byte(&sounddata_data[sounddata_length-1]);
sample = 0;
sei();
}
void setup()
{
pinMode( pinSwitch1, INPUT );
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
startPlayback();
}
void loop()
{
while (true);
}
以下更改将允许您在开关引脚出现下降沿时开始播放。您可能需要调整以避免开关“反弹” 首先,添加一个全局变量来记录最后一个开关状态:
int-lastSwitchState;
将setup()
更改为
void setup(){
引脚模式(引脚开关1,输入);
引脚模式(LED引脚,输出);
数字写入(ledPin,高电平);
lastSwitchState=digitalRead(pinSwitch1);
}
而您的loop()
函数
void循环(){
延迟(50);
int switchState=数字读取(pinSwitch1);
if(switchState!=lastSwitchState){
lastSwitchState=开关状态;
如果(开关状态==低){
startPlayback();
}
}
}
中断与轮询
您可以使用中断,而不是轮询主环路()内的开关引脚。你会经常这样做。然而,中断仅在某些引脚上可用,我认为上述方法在概念上更简单。重复
#ifndef _HEADERFILE_H // Put these two lines at the top of your file.
#define _HEADERFILE_H // (Use a suitable name, usually based on the file name.)
const int sounddata_length=32000;
//const int sounddata_sampleRate=20000;
const unsigned char sounddata_data[] PROGMEM = {
15,1,49,0,150,0,138,0,219,255,133,0,176,0,15,1,210,
//There are many lines of more numbers in between that I cut out to save space
};
#endif // _HEADERFILE_H // Put this line at the end of your file.