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), график, который я печатаю и отображаю через последовательный график звука, не изменится. Поэтому мне пришлось закрыть его и открыть снова, чтобы увидеть изменения. Вопрос в том, как я могу добиться непрерывного чтения этого в режиме реального времени? Большое вам спасибо.

, 👍4


1 ответ


Лучший ответ:

4

сбросьте номер результата на 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);   
   // снова включить АЦП
}
,

Хорошо, я сначала попробую, @SNahar