Определение сопротивления контроллером без АЦП

в 8:55, , рубрики: diy или сделай сам, микроконтроллер, метки:

Собственно стала такая вот задача — несколько раз в секунду снимать показания потенциометра. Целевой приемник информации — контроллер ATmega32. Имеет встроенный АЦП, но выдаваемый им результат имел разрешение 2-3 бита, а остальные биты несли в себе мусор.

Первое что пришло на ум — купить внешний АЦП и прикрутить к контроллеру. Но не было не времени не желания разбираться с еще одним устройством. Решил попробовать другой метод, в работоспособности которого не был уверен, но тем не менее схема оказалось вполне рабочей и дала точность порядка 8 бит (может и больше, не проверял).

Собственно идея заключается в том, что цифровым входом контроллера измеряется скорость разряда конденсатора. Конденсатор заряжается до напряжения питания через низкое сопротивление, потом запускается отчет времени, и конденсатор разряжается через потенциометр. Когда напряжение на конденсаторе упадет до 1.4В (напряжение переключения входа контроллера в низкий уровень), значение логического уровня на входе переключится, и отчет времени прекращается. Полученное время разряда пропорционально текущему сопротивлению потенциометра.

Схема устройства:

image
A0, A1 — ножки МК, цифровой порт А.

Транзистор в схеме применяется для того, что бы напряжение, до которого зарядится конденсатор не зависело от текущего положения потенциометра.

Расчет схемы.

Для обеспечения хорошей точности измерения необходимо выбрать элементы схемы таким образом, что бы время разряда при крайних положениях потенциометра отличалось примерно на порядок. Вообще чем больше тем лучше, но всему ж есть придел.
Формула времени разряда конденсатора через резистор(с вики):
image

Необходимо подобрать R и С таким образом, что бы обеспечить время разряда с 5В (ВУ) до 1.4В (уровень переключения порта в логический 0) за время 0.02сек при максимальном сопротивлении, и за время 0.002сек при минимальном сопротивлении. При этом величина С постоянная в обеих случаях, а R отличается на 50кОм (величина потенциометра). Время было выбрано из соображений точности, скорости работы микроконтроллера, и подобрано для наиболее точного соответствия имеющимся номиналам резисторов и конденсаторов. (контроллер работает на частоте 8МГц)
Решая систему уравнений определяем значение резистора R13 и конденсатора C1.
image

Здесь не учтено внутреннее сопротивление входа контроллера, но скорость работы контроллера позволила программно настроить схему и подобрать коэффициент для перевода времени разряда в диапазон 0..255.

R12 используется для зарядки конденсатора и должен быть небольшим, R14 должен обеспечивать режим насыщения транзистора при любом возможном токе.

Окончательный выбор значений элементов схемы:

R12 = 220 Ом;
R13 = 6.8 кОм;
R14 = 1 кОм;
R 15 = 0..50 кОм;
С1 = 1 мкФ.

Для заряда конденсатора транзистор выключается, а ножка A0 настраивается на вывод высокого уровня (DDRA = 3, PORTA = 1). и делается задержка на достаточно больше время для заряда конденсатора. Затем A0 переключения в состояние ввода, и открывается транзистор (DDRA = 2, PORTA = 2). конденсатор начинает разряжаться, время разряда отслеживается пустым циклом.

Ниже собственно приведен код функции, занимающийся измерением скорости разряда.

uint8_t readADC()
{ // контенсатор уже заряжен
DDRA = 2;
PORTA = 2;
int i = 0, t = 0;
while (PINA & 1){
t++;
if (t == 43) i++, t = 0; // константа 43 подобрана экспериментально
}
PORTA = 1; // что бы конденсатор опять заряжался
DDRA = 3;
//если необходимо оцифровывать беспрерывно,
//нужно сделать небольшую задержку, что бы конденсатор
//успел зарядится до высокого уровня напряжения
i -= 40; // подобрано экспериментально
if (i < 0) i = 0; // вдруг появятся помехи и значения будут неожиданные
if (i > 255) i = 255;
return i;
}

Cхема удачно работает, снимаемые 8 бит стабильны. Вероятно можно ускорить работу схемы, пересчитав параметры для меньшего времени, но ограничениями на этого являются входная паразитная емкость входа и время работы контроллера.
Не проверял, но думаю, что можно уменьшить время разряда в10 — 20 раз, и это не скажется на точности результата.

Автор: LightKeeper

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js