Когда АЦП снимает показания?

Я экспериментирую с "двухвыводным измерителем емкости" и пытаюсь сделать его более точным. В настоящее время я заставил Arduino читать интервалы 62,5 нс, но это означает, что время чтения АЦП занимает большую часть интервала. В настоящее время я использую значение предварительного делителя 8 на АЦП. К сожалению, непрерывное чтение на самом деле не вариант, поэтому я ограничен временем чтения около 8 мкс вместо 6,5 мкс. Это не такая большая проблема, так как я знаю, что чтение займет около 8 мкс из экспериментов, однако я не знаю, когда в течение этого интервала 8 мкс происходит фактическое чтение.

Итак, вот мой вопрос: принимает ли adc среднее значение в течение этих 8 мкс, "блокирует" ли он биты в начале или когда именно происходит считывание?

Ссылка на измеритель емкости, особенно третий: http: //www.circuitbasics.com/how-to-make-an-arduino-capacitance-meter/#comment-363733)

, 👍0

Обсуждение

Синхронизация аналогового чтения() не имеет решающего значения в программе «2-контактный измеритель емкости». Только время между pinMode(OUT_PIN, INPUT_PULLUP); и pinMode(OUT_PIN, INPUT); (переменная t) должно быть известно с высокой точностью., @Edgar Bonet

@EdgarBonet Почему именно время для pinMode (OUT_PIN, INPUT); важный момент, после этого мы считываем показания с АЦП, изменение режима вывода «задерживает» напряжение или что здесь происходит?, @Beacon of Wierd

Да. Режим вывода INPUT_PULLUP заряжает конденсатор через внутренний подтягивающий резистор. Режим «ВХОД» останавливает процесс и, как вы говорите, «запирает» заряд в конденсаторе. Время между двумя изменениями режима является временем зарядки, которое является релевантным временем для определения емкости., @Edgar Bonet

@EdgarBonet Спасибо! Это знание значительно увеличило точность, которой я могу достичь. Я, вероятно, просто гоняюсь за машинами в этот момент, но вы случайно не знаете, когда напряжение «застревает». Я использую PORTC для включения и выключения подтягивающего резистора, и кажется, что это занимает всего 1 тактовый цикл, однако я не уверен, лучше ли измерять время до, после или между переключателями. В настоящее время я измеряю время после переключения., @Beacon of Wierd

Считайте время до или после переключения PORTC. Это не имеет значения, пока вы делаете это последовательно. Если вы взяли одно показание _до_ включения подтягивания, а другое _после_ его отключения (или наоборот), вы получите небольшую ошибку синхронизации. Для максимальной надежности делайте это с отключенными прерываниями, например, cli(); ПОРТС |= _BV(PC2); время_начала = TCNT1; сэй();, @Edgar Bonet

@EdgarBonet Может ли отключение прерываний испортить обновление TCNT2? Я имею в виду, что это не прерывание, которое сбрасывает его на 0, когда оно переполняется в режиме CTC, верно?, @Beacon of Wierd

Нет, TCNT2 не использует прерывание для сброса., @Edgar Bonet


1 ответ


1

АЦП представляет собой АЦП типа "Последовательное приближение". Это работает следующим образом:

  1. Снимок входного напряжения на небольшом конденсаторе
  2. Создание опорного напряжения
  3. Сравнение напряжения на конденсаторе с эталонным напряжением
  4. Уточнение эталонного напряжения
  5. Возвращайтесь к пункту 3, пока не добьетесь желаемой точности.

Там нужно много "времени":

  • Конденсатор может точно сохранять напряжение только до тех пор, пока саморазряд (ток утечки) не вызовет падение напряжения (это определяет максимальное количество времени, которое может потребоваться для считывания показаний)
  • Каждое уточнение опорного напряжения и его сравнение занимает один такт тактового сигнала АЦП. Также есть несколько «установочных» тактов часов. Это определяет минимальное количество тактов АЦП, необходимое для считывания (13)
  • ЦАП и компаратору требуется определенное время для работы каждого тактового импульса, что ограничивает максимальную тактовую частоту, на которой может работать АЦП.

Итак, у вас есть "золотое пятно" скорости (например, "Зона Златовласки" Солнечной системы). Установите АЦП слишком медленно или попытайтесь получить от него слишком высокое разрешение, и вы потеряете точность из-за падения напряжения на конденсаторе. Установите его слишком быстро, и ЦАП не сможет угнаться за ним, и вы потеряете точность из-за неправильного напряжения сравнения.

Ну, это внутренности. Кроме того, у вас есть API Arduino. Это добавляет еще один уровень сложности. analogRead() — это блокирующая операция. Это:

  1. Настраивает контакт ввода-вывода (при необходимости)
  2. Включает АЦП (при необходимости)
  3. Настраивает ADC MUX на правильный канал
  4. Начинает конверсию
  5. Некоторое время сидит, сложа руки.
  6. Читает результат конверсии.
  7. Возвращает его вам

И это происходит (кроме, может быть, 1 и 2) каждый раз, когда вы читаете показания. Это нормально для считывания показаний потенциометра, LDR и т. д. Но бесполезно, если вы хотите делать быстрые показания с привязкой ко времени.

Вместо этого вам нужно немного раздвинуть границы и отойти от Arduino API. Многое из того, что делает АЦП, выполняется без вмешательства ЦП. Ручная настройка АЦП для непрерывного чтения и запуска прерывания после завершения преобразования, а затем использование этого прерывания для захвата результата сравнения и запуска нового (или использование прерывания по таймеру для чтения предыдущего результата и запуска нового чтения ) даст вам гораздо больше контроля над АЦП и точно, когда что-то происходит.

Итак, теперь, чтобы ответить на ваш главный вопрос «когда в течение этого интервала 8 мкс происходит фактическое чтение» в контексте того, как работает АЦП:

В тот момент, когда конденсатор SAH отсоединяется от MUX, начинается последовательность сравнения.

Тем не менее, когда именно, это субъективно. Если вы используете API Arduino (analogRead()), то он находится в какой-то момент рядом с началом вызова функции, но не в его начале.

Если вы настроите его вручную и запустите из прерывания таймера, он будет на втором (из 13) заднем фронте тактового сигнала ADC после того, как ADSC был установлен в ВЫСОКИЙ уровень.

Есть также режимы "Free Running" и "Auto Trigger", время которых такое же, как и для одиночной конверсии. Обратите внимание, что первое преобразование, выполняемое в любом режиме, налагает «вводную» последовательность тактовых импульсов, в которой инициализируются мультиплексор АЦП и ЦАП опорного напряжения.

Всю эту синхронизацию можно найти на рисунках 23-4 и 23-5 на странице 209 Техническое описание ATMega328P. На странице 210 есть удобная таблица, в которой указано, сколько циклов АЦП с начала преобразования происходит при выполнении выборки и удержания и сколько времени занимает преобразование в тактовых циклах.

Для лучшей пропускной способности вы хотите использовать режим "Free Running" и читать и сохранять результат ADC в прерывании, которое запускает ADC. Для наиболее точной и контролируемой синхронизации вы хотите использовать режим автоматического запуска с таймером для источника запуска и снова считывать результат в прерывании АЦП.

,

Вау, это был потрясающий ответ: D Чрезвычайно подробный: D Я не думаю, что свободный режим работы для меня будет работать, так как аналоговые выводы будут использоваться для вывода и аналогового чтения. Тем не менее, я столкнулся с режимом прерывания с низким уровнем шума, который работает очень хорошо. Тем не менее, я не могу измерить его скорость (поскольку все таймеры сбиваются), вы случайно не знаете, сколько времени требуется, чтобы Arduino заснул и запустил АЦП? :с, @Beacon of Wierd