Скорость АЦП. Не понятное поведение

XanderEVG
Offline
Зарегистрирован: 06.10.2017

Здравствуйте.  Пытаюсь понять сколько раз в секунду можно получить результат из АЦП.

Исходные данные: Arduino nano, atmega328, 16Мгц

написал тестовый скетч, вот он:


volatile unsigned int count=0;
volatile int analogVal;

ISR(ADC_vect){
  //Считаем сколько раз возникло прерывание, раз в секунду в loop обнуляем
  analogVal = ADCH;
  count++; 
}

void setup() {
  Serial.begin(115200);

  ADCSRA = 0;  
  ADCSRB = 0;
  ADMUX = 0;

  //REFS=01 - ACC
  ADMUX |= (1<<REFS0);  
  ADMUX |= (1<<ADLAR);  

  ADCSRA |= (1<<ADEN); 
  ADCSRA |= (1<<ADATE); 
  ADCSRA |= (1<<ADIE); 


  //Предделитель. Макс скорость при предделителе = 32
  ADCSRA |= (1<<ADPS2); 
  ADCSRA |= (0<<ADPS1); 
  ADCSRA |= (1<<ADPS0); 

  //Стартуем
  sei();
  ADCSRA |= (1<<ADSC);  
  
}

void loop() {
    unsigned int temp;
    cli();
    temp=count;
    count=0;
    sei();
    Serial.println(temp);
    delay(1000);
}


Проблема в следующем. Опытным путем выяснил что при предделителе = 32 (ADPS2:0 = 101) скорость максимальна, count = 38463

При уменьшении предделителя скорость падает в 3 раза, например при предделителе = 16 (ADPS2:0 = 100), ADCSRA |= (1<<ADPS2);

ADCSRA |= (0<<ADPS1);

ADCSRA |= (1<<ADPS0); 

count = 11392

 

Итак, вопрос. это я где то накосячил или нет. если код в порядке то в чем проблема? Ведь при уменьшении предделителя частота выборки должна увеличиваться, а у меня уменьшается начиная с 32. 

Приведу цифры(предделитель -> count):

128 -> 9618

64 -> 19236

32 -> 38463

16 -> 11392

8 -> 22819

4 -> 45910

2 -> 49623   //в документации написано что max скорость = 76.9kSPS, если я правильно ее понял

Почему при предделителе равном 16 такое аномальное значение?

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Не вчитывался, но сразу видно что в unsigned int ничего не влезет, меняйте на unsigned long и все встанет на свои места

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Тут в проектах есть несколько тем за осцилоскопы. Максимально, что мне удалось выжать с Нанки это 490 ksps с одной ноги АЦП .. кажется, точно не помню. Код не смотрел, но по прерываниям скорость в целом получается низкая из-за пролога и эпилога обработчика прерывания. В отличии от Мега2560, Нано нормально гонится до 27Мгц включительно, но на скорости АЦП это практически не сказывается.

79ksps это предельная скорость работы мультиплексора АЦП и при прямом чтении достигается на частоте АЦП = 1Мгц. Это для нормального сигнала. Для диф.режима 15ksps похоже "пердел".

XanderEVG
Offline
Зарегистрирован: 06.10.2017

По идее должно хватить. по документации максимальная частота Ацп 79000 выборок в секунду. т е на минимальном значении предделителя счетчик бы переполнился и значение было бы в районе 15000.

сделаю позже 4 байта, но помоему проблема не в этом

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

А я вот тогда не поленился взял уно взял ваш скетч и поигрался, поэтому пишу не с потолка. При предделителе 2 было значение если память не изменяет 250к или это на div4 было. В общем во всяком случае логика будет правильная, при уменьшении предделителя переменная будет увеличиваться. А дальше уже надо смотреть сколько там kSPS можно выжать

XanderEVG
Offline
Зарегистрирован: 06.10.2017

У вас какой контроллер?

Поменял на long, ничего не изменилось. Добавил проверку переполнения:

volatile unsigned long count=0;
volatile unsigned long count2=0;
volatile int analogVal;

ISR(ADC_vect){
  //Считаем сколько раз возникло прерывание, раз в секунду в loop обнуляем
  analogVal = ADCH;
  count++; 
  if(count>1000000)count2++;
  
}

Переполнения не происходит. И самое непонятное, при предделителе 2 частота выросла до 52000. если ничего более не меняя закомментить   строку "if(count>1000000)count2++;" значение count = 35300, хотя в прошлый раз было около 49к. я вообще перестал понимать что происходит, похоже нужно деасемблировать и смотреть что там накручено оптимизатором.

 

может дело в том что это китайский клон ардуины с алиэксперсса?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

У меня китайская уна на 328атмеге. Дома буду еще раз скомпилирую и пришлю

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Да, кстати, а в 38 строке меняли инт?

У меня с вашим кодом при делителе 2 и 4 получается 258к при делителе 8 получается 158к ну и так далее по убывающей

XanderEVG
Offline
Зарегистрирован: 06.10.2017

Огромное спасибо, действительно проблема в этом!

У меня   при делителе 2 и 4 получается ~230к. вероятно в документации указано для частоты 1 мгц, не думал что частота будет 230к в сек...