Необходимые знания: [HW] Andurite moodul, [HW] Kasutajaliidese moodul,
[ELC] Pingejagur, [AVR] Analoog-digitaalmuundur, [LIB] Analoog-digitaalmuundur,
[LIB] 7-segmendiline LED indikaator
Потенциометр это переменный резистр с тремя контактами, где между двумя крайними контактами находится фиксированное сопротивление, а между крайними и средним контактами - переменное сопротивление. Потенциометр, в принципе, является и делителем напряжения, где сопротивления образуются между крайними и средним контактами. Синоним потенциометра (на английском языке potentiometer) - реостат (на английском rheostat).
Типичный потенциометр состоит из сопротивления с токопроводящей поверхностью и из скользящего по ней подвижного контакта – движка. Чем ближе движок к углу сопротивления, тем меньше сопротивление между движком и этим углом, и наоборот. В роли сопротивления может выступать материал с большим удельным сопротивлением или обмотка скрученная из проволоки сопротивления. Существуют потенциометры как с линеарным, так и логарифмическим сопротивлением и позиционным отношением. Большая часть потенциометров поворотные (пример на картинке справа), но имеются так же и сопротивления скользящего типа. Особенный тип потенциометра это дигитальные потенциометры, в которых регулировка сопротивления происходит внутри микросхемы в соответствии с управляющими сигналами.
На плате модуля «Датчики» Домашней Лаборатории находится поворотный потенциометр 4,7 kΩ. Потенциометр подключен между землей и +5 V потенциалами, а движок соединен с каналом 3 аналого-дигитального преобразователя микроконтроллера. В таком случае можно регулировать выходное напряжение потенциометра в пределах от 0 до 5 V. Если опорное напряжение аналого-дигитального преобразователя AVR взять с вывода AVCC, то выходное напряжение потенциометра получит дигитальное значение на протяжении всей границы его регулирования. Для использования ADC AVR в библиотеке Домашней Лаборатории написаны следующие функции:
// // Типы данных настроек // typedef enum { ADC_REF_AREF = 0x00, ADC_REF_AVCC = 0x01, ADC_REF_2V56 = 0x03 } adc_reference; typedef enum { ADC_PRESCALE_2 = 0x01, ADC_PRESCALE_4 = 0x02, ADC_PRESCALE_8 = 0x03, ADC_PRESCALE_16 = 0x04, ADC_PRESCALE_32 = 0x05, ADC_PRESCALE_64 = 0x06, ADC_PRESCALE_128 = 0x07 } adc_prescale; // // Запуск ADC // void adc_init(adc_reference reference, adc_prescale prescale) { // Разрешение работать ADC, выбор частотного делителя ADCSRA = bit_mask(ADEN) | (prescale & 0x07); // Выбор опорного напряжения ADMUX = (reference & 0x03) << REFS0; } // // Преобразование значения обозначеного канала // unsigned short adc_get_value(unsigned char channel) { // Обозначение канала ADMUX = (ADMUX & 0xF0) | (channel & 0x0F); // Начало преобразования bit_set(ADCSRA, ADSC); // Ожидание окончания преобразования while (bit_is_set(ADCSRA, ADSC)) { asm volatile ("nop"); } // Возвращение результата return ADCW; }
Функцию adc_init нужно вызвать в начале программы, с помощью чего настраивается работоспособность AVR-а ADC. Cледует выбрать опорное напряжение с вывода AREF или AVCC, или наоборот входное фиксированное напряжение 2,56 V. В добавок нужно обозначить рабочий такт преобразователя, а точнее предварительный делитель частоты, с помощью которого делится рабочий такт микроконтроллера. Преобразование происходит быстрее при использовании более высокого такта, но в таком случае может пострадать точность измерения. Для измерения имеется функция adc_get_value с помощью которой можно выбрать канал и которая возвращает 10-битовый результат измерения в виде 16-битного целого числа. Функция измерения является блокирующей, т.е. она остается ждать конца преобразования и возвращает результат только тогда, когда измерение совершено.
В примере программы используется только что объясненная библиотека аналогово-дигитального преобразователя и 7-сегментного цифрового индикатора LED. Значение 10-битного аналогово-дигитального преобразователя умножается на десять и делится на 1024, чтобы получить значение в пределах от 0 до 9. Значение 10 не может возникнуть, т.к. в языке Си в частном рассчитывается целочисленное, а не округленное значение. Для получения более точного результата измерения используется функция усреднения результата преобразователя. В качестве результата рабочая программа показывает на индикаторе цифры от 0 до 9, соответственно положению индикатора.
// // Пример программы модуля «Датчики» Домашней Лаборатории. // На 7-сегментном цифровом индикаторе отображается положение потенциометра. // #include <homelab/adc.h> #include <homelab/module/segment_display.h> // // Выбор канала // // 1 = Фоторезистор // 2 = Терморезистор // 3 = Потенциометр // #define ADC_CHANNEL 3 // // Основная программа // int main(void) { int value; // Настройка 7-сегментного цифрового индикатора segment_display_init(); // Настройка ADC преобразователя adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); // Бесконечный цикл while (true) { // Считывание значения, округленного в 4 раза value = adc_get_average_value(ADC_CHANNEL, 4); // Отображение показаний в сотых segment_display_write(value * 10 / 1024); } }