Почему этот код не воспроизводит преобразованный заголовочный файл wav2c через Arduino на мой динамик?
Я использовал этот конвертер wav2c для преобразования файла .wav в C, который я могу поместить в файл заголовка. Мне удалось поместить преобразованный звук в файл h, но программа, на которую я ссылаюсь, работает неправильно. Код компилируется и загружается в Arduino, но звук не воспроизводится. Я использовал код здесь для реализации преобразованного звука. Я использую динамик 8 Ом 0,25 Вт. Я не программист и не специалист по электронике, так что, скорее всего, я сделал что-то не так. Любая помощь приветствуется!
Примечание. Динамик работает с простым тональным наброском.
Код в заголовочном файле (минус сотни строк значений для аудио)
#ifndef _HEADERFILE_H // Поместите эти две строки в начало файла.
#define _HEADERFILE_H // (Используйте подходящее имя, обычно основанное на имени файла.)
const int sounddata_length=10000;
//const int sounddata_sampleRate=8000;
const unsigned char sounddata_data[] PROGMEM = {
15,1,49,0,150,0,138,0,219,255,133,0,176,0,15,1,210,254,16,1,197,255,65,0,9,0,227,0,127,254,87,0,175,1,61,254,132,1,135,255,21,1,72,0,104,1,172,0,122,0,213,1,65,255,188,1,100,1,215,0,210,255,59,2,17,0,193,0,200,2,207,255,203,0,65,1,17,1,169,255,121,2,112,0,193,255,65,255,252,255,232,0,101,255,88,2,4,0,26,255,
// Еще несколько сотен строк этих цифр для аудио
105,108,101,45,49,46,48,46,50,52,41,0,105,100,51,32,42,0,0,0,73,68,51,3,
0,0,0,0,0,31,84,88,88,88,0,0,0,21,0,0,0,83,111,102,116,119,97,114,101,0,76,97,118,102,53,50,46,57,51,46,48,0,};
#endif // _HEADERFILE_H // Поместите эту строку в конец вашего файла.
Вот код, который я использовал со страницы Arduino Playground для воспроизведения звука из файла заголовка.
#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#define SAMPLE_RATE 8000
#include "Test.h"
int ledPin = 3;
int speakerPin = 11; // Может быть 3 или 11, два выхода ШИМ подключены к Таймеру 2
volatile uint16_t sample;
byte lastSample;
void stopPlayback()
{
// Запретить прерывание воспроизведения по семплам.
TIMSK1 &= ~_BV(OCIE1A);
// Полностью отключить таймер для выборки.
TCCR1B &= ~_BV(CS10);
// Отключить таймер PWM.
TCCR2B &= ~_BV(CS10);
digitalWrite(speakerPin, LOW);
}
// Это вызывается на частоте 8000 Гц для загрузки следующего семпла.
ISR(TIMER1_COMPA_vect) {
if (sample >= sounddata_length) {
if (sample == sounddata_length + lastSample) {
stopPlayback();
}
else {
if(speakerPin==11){
// Уменьшить до нуля, чтобы уменьшить щелчки в конце воспроизведения.
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);
// Настройте Таймер 2 для выполнения широтно-импульсной модуляции на динамике
// приколоть.
// Использовать внутренние часы (данные стр. 160)
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
// Установить быстрый режим ШИМ (стр. 157)
TCCR2A |= _BV(WGM21) | _BV(WGM20);
TCCR2B &= ~_BV(WGM22);
if(speakerPin==11){
// Выполнить неинвертирующий ШИМ на выводе OC2A (стр. 155)
// На Arduino это контакт 11.
TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
// Без предделителя (стр. 158)
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Установить начальную ширину импульса на первую выборку.
OCR2A = pgm_read_byte(&sounddata_data[0]);
} else {
// Выполнить неинвертирующий ШИМ на выводе OC2B (стр. 155)
// На Arduino это контакт 3.
TCCR2A = (TCCR2A | _BV(COM2B1)) & ~_BV(COM2B0);
TCCR2A &= ~(_BV(COM2A1) | _BV(COM2A0));
// Без предделителя (стр. 158)
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Установить начальную ширину импульса на первую выборку.
OCR2B = pgm_read_byte(&sounddata_data[0]);
}
// Настройте Таймер 1 на отправку выборки при каждом прерывании.
cli();
// Установка режима CTC (сброс таймера при совпадении сравнения) (стр. 133)
// Необходимо установить OCR1A *после*, иначе он сбрасывается на 0!
TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
// Без предделителя (стр. 134)
TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
// Установить регистр сравнения (OCR1A).
// OCR1A — это 16-битный регистр, поэтому мы должны сделать это с помощью
// прерывания отключены для безопасности.
OCR1A = F_CPU / SAMPLE_RATE; // 16е6/8000 = 2000
// Разрешить прерывание, когда TCNT1 == OCR1A (стр. 136)
TIMSK1 |= _BV(OCIE1A);
lastSample = pgm_read_byte(&sounddata_data[sounddata_length-1]);
sample = 0;
sei();
}
void setup()
{
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
startPlayback();
}
void loop()
{
while (true);
}
@Ryan F, 👍2
Обсуждение1 ответ
Эта программа использует функцию Timer 2 PWM для создания аудиовыхода на контакты OC2A или OC2B. На Arduino Uno эти контакты имеют маркировку «11» и «3» соответственно, и программа несет это отображение как неявное предположение. Вы пытаетесь запустить программу на Arduino Mega, которая имеет другую распиновку. Например, на Mega:
- OC2A = цифровой 10
- OC2B = цифровая 9
Вы можете легко перенести программу на Mega, заменив каждую ссылку к контактам 11 и 3 на 10 и 9 соответственно. Например, каждое вхождение
if(speakerPin==11){
становится
if(speakerPin==10){
Обязательно исправьте комментарии, чтобы они соответствовали код.
И вам, конечно же, следует выбрать соответствующий пин для вашего динамика.
Примечание: вы нагружаете выходной контакт, если подключаете его напрямую. к динамику 8 Ω. Это нормально для теста, пока вам все равно слишком много о сроке службы вашего Arduino.
- Выводы прерываний Arduino Mega 2560 и отображение портов с помощью поворотного энкодера
- Измерение скорости двигателя постоянного тока с помощью поворотного энкодера
- Сообщение об ошибке: "exit status 1 expected initializer before 'void'."
- Arduino Mega TIMER1 интервал в одну секунду
- Использование клавиатуры для воспроизведения аудиофайла на Arduino Mega и Adafruit VS1053
- Serial — отправляет данные в Arduino, пока Arduino отправляет данные
- Mega 2560 не воспроизводит аудиофайл, когда я хочу. Он играет, когда выполняется первое условие, но не другое
- НЕ декодер MP3 в реальном времени
Вы используете правильный вывод для вывода?, @jsotola
Поместите резистор минимум 125 Ом последовательно с контактом и динамиком, чтобы ограничить ток от контакта до 40 мА макс. 10 000 сэмплов считываются с частотой 8 000 Гц = 1,25-секундная вспышка звука. Это то, что вы ожидаете?, @CrossRoads