Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
26.07.2013, 13:44
|
|
Временная регистрация
Регистрация: 10.10.2011
Адрес: Донецк
Сообщений: 94
Сказал спасибо: 65
Сказали Спасибо 48 раз(а) в 13 сообщении(ях)
|
Re: Убрать дрожание в последнем разряде
Сообщение от va11
|
Работа от внутр. генератора 8Мгц. АЦП внутренний. Есть источник опорного напряжения.
Индикация меняется примерно 2р/сек. За это время проводится 500 измерений в 2х каналах.
Используется только для отображения в данном проекте.
Дин. ндикация работает от 8-битного таймера с прескалером 8
|
Ясно (Что ниче не ясно )
т.е у вас ацп меряет проводит измерение раз в миллисекунду напряжения, которое выводится на экран и еще что-то. Значит АЦП работает в одиночном режиме... и что имеем?...
А перед выводом эти 500 прочитанных значений усредняются? если да то как? Я например стараюсь использовать вместо деления сдвиги. Почему и суммирую по 8 или по 16 значений (в вашем случае ближе всего 512) это связано с тем, что в авр-ках нет аппаратного деления и компиляторы могут тААкого там наделить... Еще несколько советов. Если каналы используют разное опорное напряжение их нельзя переключать слишком часто, да и вообще все каналы желательно измерять относительно одной опоры. На источник же опорного напряжения советую взглянуть осцилом (если конечно он есть )
|
|
|
|
26.07.2013, 13:49
|
|
Прохожий
Регистрация: 22.09.2011
Сообщений: 2
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Убрать дрожание в последнем разряде
медианный фильтр или небольшой интегратор Вам помочь должен.
static int result_sample = 0;
static const int tau = 4; /* под задачу подберите константу эту, если 2ки степень использовать то можно не делить а сдвигать */
int sample_processing(int valueFromAdc) // ‹‹ это калбек от IRQ окончания семплирования
{
static int accumulator = 0;
accumulator += valueFromAdc;
accumulator -= result_sample;
result_sample = accumulator / tau;
}
или FIR используйте, но проще настраивать интегратор практика говорит так.
хотя и туповатый он.
|
|
|
|
26.07.2013, 14:21
|
|
Вид на жительство
Регистрация: 30.10.2007
Адрес: Ростов-на-Дону
Сообщений: 285
Сказал спасибо: 23
Сказали Спасибо 39 раз(а) в 33 сообщении(ях)
|
Re: Убрать дрожание в последнем разряде
Переход между цифрами (неважно, сколько там разрядов) 1, 2 или 50 имеет нулевую ширину. Даже если 100 бит АЦП и 1000-крантное усреднение, но вы попали на 4,99999999999-5,000000000001, то будет дрожать.
Поэтому идеи про интегрирование, количество разрядов АЦП, тип микроконтроллера и, даже, целочисленную арифметику сами по себе не годятся!
Надо дорабатывать идею прямо из пятого поста, от alvadep: "Если разница больше 1, то последнее значение выводить на индикатор и проверку делать уже относительно этого значения. "
Только не обязательно 1, а делать эдакий люфт между измеренной величиной и отображаемой на индикаторе таким образом, чтобы размах шума не изменял показания индикатора.
То есть так:
Если величина показаний менее (более) измеренной на допуск, то приравнять показания индикатора измеренной величине.
Т.е. просто сравнивать абсолютную разность с допуском.
Допуск может быть и менее и более единицы (0,1 младшего разряда, если шум 0,01, например), но погрешность будет меньше, чем допуск (так как измерения в обе стороны отклоняются).
Но в некоторых случаях при таком способе (при "0" измерений, если они только положительные и допуск единица и более) будет глюк - "0" не покажет никогда.
Последний раз редактировалось vspvsp; 26.07.2013 в 14:28.
|
|
|
|
26.07.2013, 14:23
|
|
Почётный гражданин KAZUS.RU
Регистрация: 12.11.2004
Адрес: Москва
Сообщений: 8,496
Сказал спасибо: 694
Сказали Спасибо 4,285 раз(а) в 1,962 сообщении(ях)
|
Re: Убрать дрожание в последнем разряде
Каковы результаты измерения опорного напряжения? Опорного напряжения/2?
__________________
Я не помогаю. Я провоцирую думать.
Не дай вам Бог плохих контактов.
|
|
|
|
26.07.2013, 14:35
|
|
Прописка
Регистрация: 16.02.2008
Адрес: Donbass
Сообщений: 219
Сказал спасибо: 68
Сказали Спасибо 112 раз(а) в 58 сообщении(ях)
|
Re: Убрать дрожание в последнем разряде
Сообщение от vspvsp
|
Переход между цифрами (неважно, сколько там разрядов) 1, 2 или 50 имеет нулевую ширину. Даже если 100 бит АЦП и 1000-крантное усреднение, но вы попали на 4,99999999999-5,000000000001, то будет дрожать.
Поэтому идеи про интегрирование, количество разрядов АЦП, тип микроконтроллера и, даже, целочисленную арифметику сами по себе не годятся!
|
Вы правы в том, что флуктуации последнего разряда были, есть и будут всегда и везде, в любом супер-пупер крутом цифровом измерительном устройстве.
Весь вопрос лишь в величине и периоде этих флуктуаций.
И идеи даже примитивного интегрирования в сочетании со скрпулезным вылизыванием аппаратной части и соблюдением прочих правил конструирования измерительных устройств очень даже работают.
В данном случае у автора ветки может быть масса причин дрожания, начиная от "грязного" входного сигнала или ИОН и зачанчивая тем, что у него разрядность АЦП равна дискретности индикации, тогда как по всем правилам разрядность АЦП желательна ну хотя бы в два раза выше.
Да и деление на сях запросто свою погрешность вносить может.
И прочее.
А так простейшие алгоритмы интегрирования очень даже неплохо работают, поверьте.
|
|
|
|
26.07.2013, 15:47
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.01.2007
Сообщений: 3,124
Сказал спасибо: 61
Сказали Спасибо 1,154 раз(а) в 625 сообщении(ях)
|
Re: Убрать дрожание в последнем разряде
Сообщение от KGN
|
...зачанчивая тем, что у него разрядность АЦП равна дискретности индикации, тогда как по всем правилам разрядность АЦП желательна ну хотя бы в два раза выше.
|
Расшифруйте, please.
|
|
|
|
26.07.2013, 15:54
|
|
Гражданин KAZUS.RU
Регистрация: 31.12.2010
Сообщений: 837
Сказал спасибо: 371
Сказали Спасибо 153 раз(а) в 113 сообщении(ях)
|
Re: Убрать дрожание в последнем разряде
Тогда как писали:
Запоминаем значение средней выборки за последние несколько выводов на дисплей.
Если значение в соседних отображения изменилось не более чем на какую то нами заданную величину погрешности (в нашем случае на 1), то выводим новое значение только в том случае если новое значение было получено 5 последних раз подряд (ну или другое комфортное для достижения плавности отображения количество раз).
Если значение в соседних выводах на дисплей изменилось более чем на нашу величину погрешности то выводим новый результат сразу.
Это 100% решит проблему мельтешений на дисплее.
Последний раз редактировалось Flopix; 26.07.2013 в 15:57.
|
|
|
|
26.07.2013, 16:09
|
|
Прописка
Регистрация: 16.02.2008
Адрес: Donbass
Сообщений: 219
Сказал спасибо: 68
Сказали Спасибо 112 раз(а) в 58 сообщении(ях)
|
Re: Убрать дрожание в последнем разряде
Сообщение от avp94
|
Расшифруйте, please.
|
Не понял. Что тут расшифровывать?
Это, конечно, не совсем по Котельникову, но близко.
При таком раскладе, когда на 999 единиц индикации приходится всего 1024 отсчета АЦП Вы чисто на одной математике пересчета ацэпэшных попугаев в реальную физическую величину практически гарантированно получаете ошибку в плюс/минус 1 единицу. Даже при идеальном АЦП.
Поэтому в серьезных мерялках разрядность АЦП крайне желательна на порядок выше требуемой точности (дискретности индикации), чтобы нивелировать ошибку математики. Ну а в 2 раза - это минимум.
Ну или АЦП (входной делитель/усилитель или опору) настраивать так, чтобы обходиться совсем без математики, то есть чтобы одной единице отсчета АЦП строго соответствовала одна единицйа младшего разряда индикации. Как это сделано в китайских тестерах
|
|
|
|
26.07.2013, 16:21
|
|
Гражданин KAZUS.RU
Регистрация: 31.12.2010
Сообщений: 837
Сказал спасибо: 371
Сказали Спасибо 153 раз(а) в 113 сообщении(ях)
|
Re: Убрать дрожание в последнем разряде
Вот в виде кода алгоритм описанный мной выше. Писал в блокноте мог и ошибиться
PHP код:
|
#define errorVal 1//значение погрешности на которое постоянно колеблется результат вывода на дисплей #define samples 5//количество последних выводов на дисплей которые будем проверять int lastSamples[samples]; int lastVal = 0;
int CalcNewValToDisplay(int newVal) { int i, viewVal ; int cnt = 0; if (abs(lastVal - newVal) ‹= errorVal) {//если новое значение отличается от старого не больше чем на errorVal //считаем сколько раз подряд за последние выводы на дисплей было такое же значение for (i = 0; i ‹ samples; i++) { if (lastSamples[i] == newVal) cnt++; } //если новое значение встречается все samples раз то выводим новое значение if (cnt = samples) viewVal = newVal; else// иначе выводим последнее выводимое значение на экран viewVal = lastVal; } else {//если больше чем на errorVal то выводим новый результат viewVal = newVal; } //запоминаем последнее выводимое значение lastVal = newVal; //обновляем данные в массиве последних отображаемых результатов for (i = 0; i ‹ (samples - 1); i++) { lastSamples[i] = lastSamples[i + 1]; } lastSamples[samples - 1] = newVal; return viewVal; }
|
Последний раз редактировалось Flopix; 26.07.2013 в 16:28.
|
|
|
|
26.07.2013, 16:24
|
|
Прописка
Регистрация: 16.02.2008
Адрес: Donbass
Сообщений: 219
Сказал спасибо: 68
Сказали Спасибо 112 раз(а) в 58 сообщении(ях)
|
Re: Убрать дрожание в последнем разряде
Сообщение от Flopix
|
Тогда как писали:
Запоминаем значение средней выборки за последние несколько выводов на дисплей.
Если значение в соседних отображения изменилось не более чем на какую то нами заданную величину погрешности (в нашем случае на 1), то выводим новое значение только в том случае если новое значение было получено 5 последних раз подряд (ну или другое комфортное для достижения плавности отображения количество раз).
Если значение в соседних выводах на дисплей изменилось более чем на нашу величину погрешности то выводим новый результат сразу.
Это 100% решит проблему мельтешений на дисплее.
|
Проблему мельтешений это может и решит. Но в то же время конкретно увеличит инерционность мерялки при штатных изменениях входного сигнала. И эта инерционность будет жутко раздражать, поверьте.
С другой стороны если Вы примете погрешность в 1, то проблему мельтешения может и не решить. Если эту погрешность увеличите, то таким образом искусственно внесете в свою мерялку дополнительную погрешность, и у Вас будут пропуски отсчетов и скачки показаний.
Алгоритмы адаптивной цифровой фильтрации достаточно сложны и вряд ли нужны в простых системах.
Я ж уже говорил, что при условии, что все остальное сделано правильно, простой интегратор с дополнительным усреднением результата текущего и предыдущего измерения (только именно с результатом предыдущего, а не с тем, что индицировали!!!) дает вполне приемлемый для большинства случаев результат. И младший разряд при стабильно-постояном входном сигнале уже не мельтешит, а плавненько шевелится туда-сюда, никого не напрягая. Как шевелится он в любом цифровом вольтметре на малом пределе измерений, даже очень наворочанном.
Но это если с остальным все в норме.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 18:18.
|
|