Официальный сайт компании Arduino по адресу arduino.cc
Скорость АЦП. Не понятное поведение
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Здравствуйте. Пытаюсь понять сколько раз в секунду можно получить результат из АЦП.
Исходные данные: 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 такое аномальное значение?
Не вчитывался, но сразу видно что в unsigned int ничего не влезет, меняйте на unsigned long и все встанет на свои места
Тут в проектах есть несколько тем за осцилоскопы. Максимально, что мне удалось выжать с Нанки это 490 ksps с одной ноги АЦП .. кажется, точно не помню. Код не смотрел, но по прерываниям скорость в целом получается низкая из-за пролога и эпилога обработчика прерывания. В отличии от Мега2560, Нано нормально гонится до 27Мгц включительно, но на скорости АЦП это практически не сказывается.
79ksps это предельная скорость работы мультиплексора АЦП и при прямом чтении достигается на частоте АЦП = 1Мгц. Это для нормального сигнала. Для диф.режима 15ksps похоже "пердел".
По идее должно хватить. по документации максимальная частота Ацп 79000 выборок в секунду. т е на минимальном значении предделителя счетчик бы переполнился и значение было бы в районе 15000.
сделаю позже 4 байта, но помоему проблема не в этом
А я вот тогда не поленился взял уно взял ваш скетч и поигрался, поэтому пишу не с потолка. При предделителе 2 было значение если память не изменяет 250к или это на div4 было. В общем во всяком случае логика будет правильная, при уменьшении предделителя переменная будет увеличиваться. А дальше уже надо смотреть сколько там kSPS можно выжать
У вас какой контроллер?
Поменял на long, ничего не изменилось. Добавил проверку переполнения:
Переполнения не происходит. И самое непонятное, при предделителе 2 частота выросла до 52000. если ничего более не меняя закомментить строку "if(count>1000000)count2++;" значение count = 35300, хотя в прошлый раз было около 49к. я вообще перестал понимать что происходит, похоже нужно деасемблировать и смотреть что там накручено оптимизатором.
может дело в том что это китайский клон ардуины с алиэксперсса?
У меня китайская уна на 328атмеге. Дома буду еще раз скомпилирую и пришлю
Да, кстати, а в 38 строке меняли инт?
У меня с вашим кодом при делителе 2 и 4 получается 258к при делителе 8 получается 158к ну и так далее по убывающей
Огромное спасибо, действительно проблема в этом!
У меня при делителе 2 и 4 получается ~230к. вероятно в документации указано для частоты 1 мгц, не думал что частота будет 230к в сек...