Arduino непрерывно считывает значение АЦП с помощью прерывания
У меня есть аудиоразъем mono jack, выступающий в качестве аналогового входа для arduino UNO. Микрофон выдает напряжение, которое изменяется с точки зрения амплитуды
(громкости) и частоты
. Чтобы получить высокую частоту дискретизации, я использую prescaler 16 и устанавливаю высокую скорость передачи данных для последовательной связи, чтобы напечатать значение. Я сохраняю аналоговое считывание с этого разъема аудио в буферный
массив с максимальным значением 256 (8 бит). Это мой код (я изменяю его из блога Ника Гаммона об ADC здесь) :
const byte adcPin = 0; // A0
const int MAX_RESULTS = 256;
volatile int results [MAX_RESULTS];
volatile int resultNumber;
void setup ()
{
Serial.begin (230400);
Serial.println ();
// таймер сброса 1
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
TCCR1B = bit (CS11) | bit (WGM12); // CTC, прескалер 8
TIMSK1 = bit (OCIE1B);
OCR1A = 39;
OCR1B = 39; // 20 uS - частота дискретизации 50 кГц
ADCSRA = bit (ADEN) | bit (ADIE) | bit (ADIF); // включить АЦП, требуется прерывание по завершении
ADCSRA |= bit (ADPS2); // Прескалер из 16
// ADCSRA |= (1 << ADPS1) | (1 << ADPS0); // 8 прескалеров для 153,8 кГц
ADMUX = bit (REFS0) | (adcPin & 7);
ADCSRB = bit (ADTS0) | bit (ADTS2); // Таймер/Счетчик1 Сравнить совпадение B
ADCSRA |= bit (ADATE); // включить автоматическое включение
}
// Полный ISR АЦП
ISR (ADC_vect)
{
results[resultNumber++] = ADC;
if(resultNumber == MAX_RESULTS)
{
ADCSRA = 0; // отключить АЦП
}
}
EMPTY_INTERRUPT (TIMER1_COMPB_vect);
void loop () {
while (resultNumber < MAX_RESULTS)
{ }
for (int i = 0; i < MAX_RESULTS; i++)
{
Serial.println (results [i]);
}
}
С помощью этого кода я получил хороший результат представления синусоидального графика звукового значения до 4000 Гц следующим образом :
Но одна вещь, которая не сработала, заключается в том, что если я изменю громкость или частоту (при отображении данных) аналогового входа (jack audio), график, который я печатаю и отображаю через последовательный график звука, не изменится. Поэтому мне пришлось закрыть его и открыть снова, чтобы увидеть изменения. Вопрос в том, как я могу добиться непрерывного чтения этого в режиме реального времени? Большое вам спасибо.
@SNahar, 👍4
1 ответ
Лучший ответ:
сбросьте номер
результата на 0 после того, как вы записали его в serial. и снова включите прерывания
void loop () {
while (resultNumber < MAX_RESULTS)
{ }
for (int i = 0; i < MAX_RESULTS; i++)
{
Serial.println (results [i]);
}
resultNumber = 0;
ADCSRA = bit (ADEN) | bit (ADIE) | bit (ADIF)| bit (ADPS2) | bit (ADATE);
// снова включить АЦП
}
- 4-битный счетчик вверх и вниз
- Включить и отключить отдельные прерывания
- Измерить количество циклов и время цифрового входа
- Проблема прерывания библиотеки MPU6050 Arduino Jeff Rowberg
- генерировать два сдвинутых по фазе ШИМ-импульса, запускаемых внешним сигналом с частотным разделением, с помощью Arduino uno?
- Включение прерывания Timer1 CompareA мгновенно вызывает прерывание?
- Таймер Arduino в режиме ctc 4 против 14
- Прерывания TIMER1 CTC не работают с avr-gcc
Хорошо, я сначала попробую, @SNahar