Частота считывания АЦП
- Войдите на сайт для отправки комментариев
Чт, 16/01/2014 - 09:34
1) Возможна ли ли частота считывания АЦП arduino pro micro 16MHz 10кГЦ ?
2) это лучше делать AnalogRead() ?
3) Как считывать значение АЦП через фиксированные промежутки времени не зная времени одного считывания. Предполагаю, что это время не постоянно ?
PS: конечно же имел в виду 10kHz, а 16 MHz частота МК
Доброго времени суток !
1) Возможно до 15 кСамплов точность считывания удовлетворительная.
2) Если считывание с 1-го входа лучше настроить непрерывное считывание, так как первое считывание занимает 23 такта АЦП, последующие 13 тактов. Функция analogRead() считывает разово следовательно требует 23 такта(не процессора, АЦП).
3) Настроить предделитель АЦП и непрерывным считыванием.
Вот быстрый analogRead(). Скорость работы ADC тут повышена со стандартных 125кГц до 500, что даёт примерно 37 тысяч измерений в секунду. Подробнее смотри назначение битов ADPS2-ADPS0. Ну и плюс сам код тут максимально быстрый.
Доброго времени суток !
1) Возможно до 15 кСамплов точность считывания удовлетворительная.
Стандартно настроенный ADC даёт в теоретическом максимуме 9600 семплов/сек, через стандартный analogRead меньше 8к.
3) Как считывать значение АЦП через фиксированные промежутки времени не зная времени одного считывания. Предполагаю, что это время не постоянно ?
Насколько точные должны быть промежутки считывания? Вариантов два: считывать в прерывании таймера или самостоятельно отмерять временные промежутки считывания и как только наступает время, считывать. Во втором случае точность может быть ниже, но нет проблем синхронизации данных между процедурой прерывания и основной программой.
Количественно ответить не могу, но предположу что в пределах +- 6...8% нормально. Суть в том, чтобы за интервал времени (интервал переменный) посчсотреть, сколько отсчетов было ниже порога (переменный порог) и сколько выше и далее принимать решение. Кроме этой задачи от мк ничего не требуется.
наверное надежнее измерять вне прерывания, чтобы не заиягивать его завершение
как пересчитать такты АЦП в средство измерения времени доступное программе, например millis() ?
Количественно ответить не могу, но предположу что в пределах +- 6...8% нормально. Суть в том, чтобы за интервал времени (интервал переменный) посчсотреть, сколько отсчетов было ниже порога (переменный порог) и сколько выше и далее принимать решение. Кроме этой задачи от мк ничего не требуется.
наверное надежнее измерять вне прерывания, чтобы не заиягивать его завершение
как пересчитать такты АЦП в средство измерения времени доступное программе, например millis() ?
Такты АЦП делить на 13 (так написано в интернете). Я бы предложил использовать всё-таки micros, чтобы иметь точность выше 0.001с. Навскидку, нетестированный код должен выглядеть примерно так:
Есть тонкость с переполнением счётчика, но это упражнение для самостоятельной работы уже :)
Господа.
нужна помощь..
в скетчах по Фурье FFT есть вариант чтения через регистры АЦП см. ниже.
Считывание идёт примерно каждые 25мкс
Как регулировать период чтения? см. текст
while(1) { // reduces jitter
cli(); // UDRE interrupt slows this way down on arduino1.0
for (int i = 0 ; i < SAMPLES ; i++) { // save 256 samples
while(!(ADCSRA & 0x10)); // wait for adc to be ready
ADCSRA = 0xf5; // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = (j << 8) | m; // form into an int
k -= 0x0200; // form into a signed int
k <<= 6; // form into a 16b signed int
vReal[i] = k; // put real data into bins
vImag[i] = 0;
}*/
Для FFT лучше всего использовать АЦП free running mode. В этом режиме получаются совершенно одинаковые промежутки между отсчетами автоматически. По окончанию измерения тут же автоматом запускается следующее. Частота выборок определяется prescaler-ом. Сразу после запуска следующего измереня генерится прерывание в котором надо просто сложить в корзинку данные предыдущего измерения.
См пример с ffft lib
Код выдрал из проекта, на компиляцию не проверял
Использовать Free Running mode это понятно...
отсчёты получаются через 20мкс... что соответствует 50килогерц сэмплинг..
А мне не нужно такой скорости... мне нужно делать измерения в диапазоне от 1 до 2000 Герц..
FFT.h который я использую рассчитан максимум на 256 измерений. Мне не нужно больше. Мне нужна скорость!
при сэмлинге 50кГц получается около 20 килогерц диапазон измерений. а мне надо 2000
при 20 тыс сильно падает разрешение по частоте...
Поэтому встаёт вопрос - как во free ranning mode управлять сэмплингом?
Скажем сделать 200микросекунд период измерений?
Читай мануал. У АЦП есть режим запуска от таймера. Заряди таймер на нужный сэмплинг и получишь запуск АЦП с нужной скоростью.
Там мануалы хилые очень...
есть пред делитель от в ADC от 2 до 128
есть пред делитель в таймере от 8 до 1024...
Есть ещё режим переполнения по регистру сравнения - тут вообще не описано ничего хотя мне кажется именно это надо применить..
В общем нужен хороший пример ибо мутно всё
отсчёты получаются через 20мкс... что соответствует 50килогерц сэмплинг..
Вы приведенный код смотрели? Там частота сэмплинга 9615 Hz
Частота сэмплинга управляется значением делителя.
// Init ADC free-run mode; f = ( 16MHz/prescaler ) / 13 cycles
Набор возможных частот не велик. Если нужна промежуточная частота, то, как уже упомнали выше, можно использовать режим запуска измерений по таймеру. Читайте даташит на процессор.
Много хороших примеров в гугле по запросу avr adc timer trigger
Много хороших примеров в гугле по запросу avr adc timer trigger
да изучал сегодня... видимо придется использовать таймер и причем 1-й - который более сложный а не 0
потому что если использовать 0-й то не будет работать micros(), а значит будет не померить фактически сэмплинг чтобы убедиться что все работает именно так как задумано те не оценить кайфухи
Коллеги извените за делетантский вопрос... вот есть у меня эта программа о всеми реистрами АЦП и всякми cli(), sei()... почему при попытке компиляции её на arduino DUE , система пишет что … нет таких переменных и операторов? Что не так с DUE? Там что виртуальный АЦП?
Там АЦП в облаке.
А вы что, программу для обычной ардуины пытаетесь на Дуе запустить? Когда вы пишете на регистрах - для каждого контроллера надо писать свой код
Использую ADC1, ADC3, ADC5, ADC7. Вопрос: подключает ли внутренний мультиплексор неиспользуемые входы к собственно ADC?
Использую ADC1, ADC3, ADC5, ADC7. Вопрос: подключает ли внутренний мультиплексор неиспользуемые входы к собственно ADC?
Ну если дадите команду подключить, то подключит. А так - нет. К ADC, в данный момент времени, может быть подключен только один пин.
)) уточню вопрос: будет ли потрачено машинное время на подключение неиспользуемого входа (входов) через мультиплексор к ADC, если эти входы не инициализированы в коде?
)) уточню вопрос: будет ли потрачено машинное время на подключение неиспользуемого входа (входов) через мультиплексор к ADC, если эти входы не инициализированы в коде?
попробуйте еще раз перечитать предыдущий ответ
уточняю: free running mode. на блок-схеме мультиплексор вроде как имеет счетный вход - то есть должен последовательно подключать все каналы к ADC
В pro micro каналы переключаются только вручную.
уточняю: free running mode. на блок-схеме мультиплексор вроде как имеет счетный вход - то есть должен последовательно подключать все каналы к ADC
Где это вам удалось найти такое? Если говорить об Атмеге, то канал выбирается записью MUXx битов в регистр ADMUX и все. Режим работы ADC к выбору канала никакого отношения не имеет.