Как сопоставить 10-битное значение АЦП с диапазоном с ограничениями

Мне нужно сопоставить 10-битный АЦП, т.е. [0-1023], с диапазоном [1-100]. Сама формула отображения является прямой "y=(xa)/(ba)*(dc)+c" для отображения x в [ab] на y в [cd].

Вход x рассчитывается как среднее значение, скажем, 1000 показаний АЦП.

Моя проблема заключается в следующем. Вход для АЦП - это потенциометр, и мне нужно вычислить x ТОЛЬКО, когда потенциометр неподвижен. Как это обнаружить? В настоящее время я это делаю, чтобы прочитать наборы из 1000 значений АЦП (по таймеру), вычислить их среднее значение и сравнить «текущее среднее значение» с «предыдущим средним значением». Если «текущее среднее — предыдущее среднее» представляет собой некоторую «+-дельту», я предполагаю, что потенциометр неподвижен, и выполняю расчет.

Есть ли лучший способ сделать это?

Изменить: предоставить дополнительные данные;

  • Я использую микроконтроллер C8051F850 от SiLabs, работающий на частоте 24,5 МГц.
  • Образцы ADC собираются каждые 100 мкс
  • Среднее значение для 2500 образцов ~ 250 мс рассчитывается для каждого набора. Таким образом, два средних значения сравниваются каждые 500 мс.
  • Моя "дельта" 10 единиц (примерно 1024/100)
  • Целочисленная арифметика, поэтому ошибки округления
Я не понимаю, какое отношение диапазон и уравнение имеют к проблеме. Возможно, вам следует просто удалить его и сосредоточиться на своей реальной проблеме. Я думаю, что реальная проблема, с которой вы столкнулись, - это своего рода проблема XY .
@pipe - я представил полную проблему и свое текущее решение, чтобы был ясен весь контекст. Это работает, но я не доволен этим и, следовательно, мой вопрос. Если есть что-то конкретное, что вы хотели бы, чтобы я разъяснил?
использовать программный фильтр нижних частот

Ответы (2)

Это «проверка гипотез в присутствии шума».

Когда мы проверяем гипотезу, мы определяем пару условий, которые мы хотим различать, а затем определяем тест, который лучше всего это сделает.

Вы определили условие «стационарно», и тест |(текущее_среднее - предыдущее_среднее)| < дельта. В этом определении подразумеваются еще два условия: движение вверх и движение вниз.

Хотя определение «стационарности» не совсем точно определено, если мы реконструируем тест, который вы разработали, чтобы выяснить, что это на самом деле означает, изменение средней позиции между первой 1000 и следующей 1000 длинной выборки из 2000 позиций, мы считаем, что это вполне разумно.

Среднее значение 1000 выборок — лучший способ вычислить среднюю позицию, если предположить, что шум в каждой выборке независим. Это также быстро, использует мало ресурсов, легко понимается и использует мало памяти (не нужно хранить все входные данные).

Разница между первым и вторым набором дает вам наилучшую оценку средней скорости банка за это время.

Теперь рассмотрим этот тестовый пример. Для первых 1000 образцов потенциометр быстро увеличивается, для следующих 1000 — быстро уменьшается. Среднее движение за этот период, рассчитанное вашим оценщиком, будет равно нулю.

Довольны ли вы тем, что это состояние будет определено как стационарное? Если нет, то мы должны изменить наше определение стационарности. Судя по вашему комментарию, вы чем-то недовольны. Но что?

Как вы видите, проблема не в самом тесте, а в (а) вашем плохом определении того, что означает «стационарный» и (б) вашем плохом определении того, что вы считаете неудовлетворительным в выполнении настоящего теста.

Тест, который вы определили, является наиболее разумным тестом для определения средней скорости в присутствии шума. Другое дело, хорошо ли это работает с физикой вашего реального мира и поведением пользователя.

Если вы обнаружите, что вам действительно нужно обнаружить ускорение, чтобы улучшить его в вашем случае, то довольно легко взять три последовательных усредненных образца, вычислить обе дельты, а затем вычислить дельта-дельта.

Если вы обнаружите, что изменение среднего размера для изменения скорости обнаружения изменений работает лучше, сделайте это.

Существуют и другие альтернативы, которые проверяют разные гипотезы. Первый заключается в вычислении двух работающих средних значений с разными постоянными времени. Это обычный фильтр для использования в качестве детектора границ при обработке изображений, но он также обнаруживает «края» в одномерных данных. Поскольку фильтры являются рекурсивными, это довольно дешево реализовать. Однако вам придется настроить две постоянные времени в соответствии с вашей ситуацией, так как же вы настроите их лучше, чем одну постоянную времени вашего текущего тестера?

Во-вторых, сделать БПФ ваших образцов. Затем вы можете сравнить энергию в ячейке постоянного тока (количество стационарных) с энергией в ячейках низкой частоты (количество движения, ускорение, изменение ускорения...), отбрасывая энергию в ячейках высокой частоты (шум чтения) . Но для этого требуется значительная память и вычислительная мощность, и это кажется излишним.

В-третьих, исходя из вашего комментария о задержке, которая является проблемой, будет одновременная оценка позиции инаклон линии с помощью линейной регрессии. Для этого существует рекурсивная формула, поэтому для вас относительно эффективно выполнять вычисления в реальном времени без дополнительной памяти. Это позволит вам «исправить» задержку в сборе данных, экстраполируя обе оценки вперед, чтобы получить усредненное положение «сейчас». Обратите внимание, что линейная регрессия может иметь проблемы с динамическим диапазоном, если она выполняется для больших наборов данных, и поскольку вы используете целочисленную арифметику, вам придется тщательно продумать реализацию. Одним из способов улучшить ситуацию было бы уничтожение и запуск линейной регрессии с гораздо более низкой частотой дискретизации, более соответствующей скорости, с которой перемещается ваш реальный мир, и времени отклика, которое вы хотите, чтобы программа имела.

Отличное объяснение! Спасибо. Моя проблема заключается в том, что когда банк движется вниз (т. е. я получаю значения от 1023 вниз) по сравнению с тем, когда банк движется вверх (т. е. я получаю значения от 0 и выше), среднее значение будет смещено к верхним или нижним концам. Это усилится, если человек очень быстро перевернет горшок. Как убрать этот перекос? Один из подходов состоит в том, чтобы использовать приведенный выше тест для обнаружения «стационарных», отбросить оба средних значения, собрать и использовать новый набор средних значений (скажем, более 100 мс) и использовать его в качестве входных данных x. Это, очевидно, увеличивает задержку к моему времени отклика, чего я хотел бы избежать, если это возможно.
Я отредактировал свой исходный пост с некоторыми дополнительными данными.
@RamanathanR ваше редактирование OP, похоже, не добавляет ничего важного, но ваш комментарий выше предполагает, что проблема заключается в задержке. Я обновил свой вопрос, чтобы решить эту проблему в последнем абзаце. Вы также можете рассмотреть возможность уменьшения частоты дискретизации до чего-то более соизмеримого с желаемым временем отклика с помощью линейного фильтра и делать «умные» вещи с гораздо более низкой частотой дискретизации. Это красиво разделит проблему и приведет к лучшей реализации. Детали выходят за рамки обсуждения на этом форуме, но мы можем поговорить в автономном режиме, если вам нужна подробная помощь.

Усреднение делает несколько вещей; и есть лучшие способы.

  1. Добавляет задержку = n * интервал выборки
  2. Уменьшает случайный джиттер на Vpp/ н
  3. Действует как 1-й фильтр нижних частот, где взвешенный фильтр может иметь такую ​​же шумовую полосу пропускания с более крутыми юбками и более низкой групповой задержкой (задержкой), как и активные фильтры.

  4. Может вызвать ошибки наложения, если сигналы превышают частоту Найквиста до усреднения, поэтому необходима некоторая фильтрация, но фильтр кирпичной стены >= 5-го порядка лучше подходит для малой задержки, которая, по сути, взвешивает значения для усреднения.

  5. Если вы ждете бездействия, а у горшка есть шум дизеринга от вибрации, это добавит чрезмерную задержку.

  6. Если вы разрабатываете другое непрерывное средневзвешенное значение, то вы можете оптимизировать групповую задержку и ошибку движения, используя такие параметры, как фильтр Калмана. Это используется в GPS и других датчиках движения, скорости и ускорения.

6б. ... как предложил @Neil_UK, вы можете выполнить БПФ для значений (или экспортировать и проанализировать), тогда я мог бы использовать согласованный фильтр для основного сигнала (скорость нарастания 10 ~ 90% = tR = 0,35 / f-3 дБ), чтобы чтобы отклонить шум, используя значения взвешивания на бродячих средних.

  1. Вы можете использовать вес скорости по средней разнице значений, чтобы предсказать положение из-за задержки и получить гладкий результат с меньшей задержкой. Затем вы можете уменьшить количество выборок, необходимых для прореживания (уменьшить разрешение), до значений 1% (0 ~ 99).

Алгоритм прореживания я оставляю другим для набросков, что является базовой алгеброй.

ps Я бы использовал инкрементальный квадратурный энкодер с фиксаторами вместо потенциометра для этого приложения, используемого в современных системах.

Спасибо за все идеи. Мне есть о чем подумать (и прочитать) :-)