Несколько слов в продолжение рассуждений о точности АЦП (см. предыдущую статью про измерение температуры). На эту тему написан не один десяток хороших книг, поэтому выделим основную проблему: для АЦП Arduino измерение идет относительно так называемого источника эталонного напряжения (который иногда называют ИОН - источник опорного напряжения).
Выбор этого источника происходит при вызове функции analogReference(type), где type может принимать одно из трех значений:
Это подводит нас к грустному, но неотвратимому выводу - точность лучше одного вольта при использовании DEFAULT нам заказана. Может быть, нам поможет INTERNAL?
Тут нас будет ждать второе разочарование - дело в том, что внутренний источник опорного напряжения ATmega требует предварительной калибровки. Надо взять эталонный источник напряжения, подать его на аналоговый пин и сравнить с внутренним, получив таким образом поправку, компенсирующую т.н. систематическую погрешность. Полученное значение надо сохранить в EEPROM микроконтроллера, поскольку оно индивидуально для каждого конкретного чипа, а в скетче считывать после старта. Немного занудно, но ничего сложного. Но, быть может, есть более простой путь?
Надо каким-то образом подать внешнее опорное напряжение на наш АЦП, да поточнее (это вариант EXTERNAL). В этом нам могут помочь:
Если подключить LM385 к AREF, то получится, что мы сузим диапазон измерений от 0 до 1.235 Вольт, что не всегда удобно. В этом случае надо либо искать похожий чип на другое напряжение, либо, пожертвовав одним аналоговым пином, оставить схему DEFAULT:
Этот прием я использовал в схеме SMPReaderUSB, для измерения напряжения внутренней литиевой батареи модуля МПО-10. Резистор R9 22К выбран с таким расчетом, чтобы через LM385 протекал небольшой ток, как и положено по его документации. Измеряемый вход BATT притянут через R10 22K к земле на тот случай, если модуль не подключен и вход ADC0 повис в воздухе.
Далее, происходит считывание с двух аналоговых пинов - к одному подключен измеряемый источник напряжения BATT (ADCm), к другому - LM385 (ADC385). Оба значения передаются в хост-программу на PC, которая вычисляет пропорцию:
Um = ADCm * 1,235 / ADC385
Значение опорного напряжения в этой формуле не участвует, и хотя зависимость по-прежнему есть, выведя это значение из формулы мы понизили его влияние на пару порядков (речь про ошибку квантования). Такой способ позволяет улучшить точность до 0,03 В, что - согласитесь - для Arduino весьма неплохо!
(в статье использованы материалы из руководства по языку Arduino)
Выбор этого источника происходит при вызове функции analogReference(type), где type может принимать одно из трех значений:
- DEFAULT: напряжение питания, около 5 Вольт (по умолчанию, после старта скетча);
- INTERNAL: встроенный ИОН - 1.1 Вольт для ATmega168 и 2.56 Вольт для ATmega8;
- EXTERNAL: напряжение на пине AREF.
Это подводит нас к грустному, но неотвратимому выводу - точность лучше одного вольта при использовании DEFAULT нам заказана. Может быть, нам поможет INTERNAL?
Тут нас будет ждать второе разочарование - дело в том, что внутренний источник опорного напряжения ATmega требует предварительной калибровки. Надо взять эталонный источник напряжения, подать его на аналоговый пин и сравнить с внутренним, получив таким образом поправку, компенсирующую т.н. систематическую погрешность. Полученное значение надо сохранить в EEPROM микроконтроллера, поскольку оно индивидуально для каждого конкретного чипа, а в скетче считывать после старта. Немного занудно, но ничего сложного. Но, быть может, есть более простой путь?
Надо каким-то образом подать внешнее опорное напряжение на наш АЦП, да поточнее (это вариант EXTERNAL). В этом нам могут помочь:
- Точный резистор: если поискать, то можно найти с погрешностью 1%, 0,1% и даже 0,01%. Есть и лучше, но это уже крутая экзотика. Из закона Ома известно, что падение напряжения на резисторе равно произведению тока на сопротивление. ОК, сопротивление-то повышенной точности, но как зафиксировать ток? Вероятно, потребуется генератор тока - это небольшая схема на операционном усилителе.
- Диод: проводя ток в прямом направлении, он попутно "съедает" вполне фиксированное напряжение. Диод ведет себя не так, как резистор - для него закон Ома не писан, но зависимость от тока все-таки есть: достаточно взглянуть на графики вольт-амперной характеристики Vf(If) в документации.
- Стабилитрон: это модификация диода (синоним "диод Зенера" :), который изначально предназначен для стабилизации напряжения. В простых схемах, не критичных к потерям энергии, его допустимо использовать с оглядкой на мощность. К сожалению, под рукой обычно оказываются только стандартные BX55C или BX79C, а у них погрешность 5%.
Тем не менее, вот простейшая схема стабилизатора питания +5В на стабилитроне (использована в Arduino minimum):
Более продвинутый вариант стабилитрона - это микросхема LM385-1.2, которая работает подобно стабилитрону, но обеспечивает падение напряжения 1.235 Вольта с точностью 1-2% (чем меньше ток, тем выше точность). Используются они практически повсеместно, выпускаются в корпусе SO и TO-92:
Если подключить LM385 к AREF, то получится, что мы сузим диапазон измерений от 0 до 1.235 Вольт, что не всегда удобно. В этом случае надо либо искать похожий чип на другое напряжение, либо, пожертвовав одним аналоговым пином, оставить схему DEFAULT:
Этот прием я использовал в схеме SMPReaderUSB, для измерения напряжения внутренней литиевой батареи модуля МПО-10. Резистор R9 22К выбран с таким расчетом, чтобы через LM385 протекал небольшой ток, как и положено по его документации. Измеряемый вход BATT притянут через R10 22K к земле на тот случай, если модуль не подключен и вход ADC0 повис в воздухе.
Далее, происходит считывание с двух аналоговых пинов - к одному подключен измеряемый источник напряжения BATT (ADCm), к другому - LM385 (ADC385). Оба значения передаются в хост-программу на PC, которая вычисляет пропорцию:
Um = ADCm * 1,235 / ADC385
Значение опорного напряжения в этой формуле не участвует, и хотя зависимость по-прежнему есть, выведя это значение из формулы мы понизили его влияние на пару порядков (речь про ошибку квантования). Такой способ позволяет улучшить точность до 0,03 В, что - согласитесь - для Arduino весьма неплохо!
(в статье использованы материалы из руководства по языку Arduino)
Спасибо за статью.
ОтветитьУдалитьВозник вопрос: а третья нога LM385 (FB) остается в воздухе в последней схеме ?
Да, в воздухе. Он ни к чему не подключается, а нужен только для единообразия - в корпусах TO-92 положено три вывода.
ОтветитьУдалить