Измерение отрицательного напряжения микроконтроллером – Как измерить отрицательное напряжение с помощью АЦП. » Хабстаб

Как измерить отрицательное напряжение с помощью АЦП. » Хабстаб

Как известно многие современные микроконтроллеры имеют встроенный многоканальный АЦП, как правило, физически АЦП всего один, а многоканальность обеспечивается с помощью мультиплексирования. Диапазон напряжений с которыми может работать АЦП определяют уровни опорных напряжений(+VREF и -VREF), они не должны выходить за диапазон питания микроконтроллера. Диапазон напряжений, питающих микроконтроллер, может быть от 0 до 3.3, либо от 0 до 5 вольт. Отсюда становится понятно что измерять отрицательные напряжения АЦП не может, а это бывает необходимо.

Для измерения отрицательных напряжений с помощью АЦП существует несколько способов, во всех примерах будем считать что -VREF = 0, а +VREF = 5 вольт.

Необходимо измерять только отрицательные напряжения, например, от -5 до 0.
В таком случае можно применить инвертирующий усилитель, построенный на операционном усилителе(ОУ), с коэффициентом усиления равным -1.


Когда на вход схемы будет приходить -1 вольт, на вход АЦП будет поступать +1 вольт. Если же сигнал, который хотим измерить нужно усилить, достаточно изменить номиналы резисторов R1 и R2.

Необходимо измерять только отрицательные напряжения, например, от -15 до 0.
В таком случае можно применить сумматор построенный на ОУ


Номиналы резисторов R1 и R2 рассчитываются следующим образом, когда Uвх = -15 вольт, суммарное падение напряжение на резисторах R1 и R2 равно 20 вольт. В этом случае на прямом входе ОУ должно быть 0 вольт, отсюда становится понятно, что на R1 упадёт 5 вольт, а на R2 упадёт 15 вольт, из этого следует, что номиналы резисторов должны соотносится как R2/R1 = 3/1. С другой стороны, так как резисторы соединены последовательно и через них течёт один и тот же ток, можно записать формулу.

Идём дальше, так как в схеме присутствует отрицательная обратная связь, напряжение на прямом и инверсном выводе должны быть равны. Когда Uвх = 0 на выходе ОУ будет 5 вольт(в данном случае ноль на входе — максимальное значение, значит на выходе должно быть максимальное значение равное 5 вольтам). В это же время на прямом входе ОУ будет 3.75 вольта, и эти же 3.75 будут на инверсном входе. Так как на выходе ОУ 5 вольт, а на инверсном входе 3.75, легко рассчитать соотношение R3 к R4(обычный делитель напряжения).

Предположив, что R1 и R4 равны 10К, получаем


R1 = 10К

R2 = 30К

R3 = 30К

R4 = 10К

Необходимо измерить напряжение, которое может изменяться от -10 до 10 вольт.

Сделать это очень просто, для этого надо создать смещение, чтобы при подаче -10 вольт на вход схемы на входе АЦП было 0 вольт, тогда при подаче 10 вольт на входе АЦП будет 5 вольт.

Реализовать это можно несколькими способами:

  • на резисторах


Номиналы резисторов рассчитываются очень просто, когда мы подаём на левый вход R2 -10 вольт на его правом выводе должно быть 0 вольт, в таком случае ток через R3 не течёт, так как на его концах отсутствует разность потенциалов.

Ток, протекающий через R2, равен


Ток, протекающий через R1, равен

Так как резисторы R1 и R2 соединены последовательно, то и токи, протекающие через них равны.

Предположим R2 равен 10K, тогда R1 равен 5K.

Осталось рассчитать R3, для этого на левый вывод R2 подадим 10 вольт, при этом на правом выводе должно быть 5 вольт, в таком случае ток через R1 не течёт.

Ток через R2 равен току через R3, получаем


получаем

R1 = 5К

R2 = 10К

R3 = 10К

Минус схемы на резисторах, это то что R2 ограничивает ток, поступающий на вход АЦП и то что любой шум в цепи питания будет попадать на вход АЦП. Хотелось бы обратить внимание на то, что у АЦП есть такой параметр, как входное сопротивление, которое, как правило, зависит от частоты сэмплирования, ниже изображена таблица в которой показано как зависит сопротивление входа от периода преобразования АЦП для STM32


сопротивление источника сигнала должно быть меньше этого значения, а последовательно включеный резистор R2 явно его не уменьшает. Говоря простыми словами за короткий промежуток времени АЦП должно получить достаточный заряд чтобы работать с ним, а резистор, включённый последовательно с входом, не даёт этого сделать.

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

  • сумматор на операционном усилителе


И снова нам поможет сумматор на операционном усилителе, как рассчитываются номиналы резисторов описано выше, но суть одна, надо взять два крайних значения, поступающего напряжения, при минимальном значении на выходе ОУ должен быть ноль, при максимальном должно быть 5 вольт(не забываем, что -VREF = 0, а +VREF = 5 вольт). Если необходимо измерять положительное и отрицательное напряжение, в качестве смещения удобно использовать половину опорного напряжения, то есть 2.5 вольта.
Вот что получилось в микрокапе, картинку можно увеличить кликнув по ней.

Схема на ОУ обладает низким выходным сопротивлением, то есть может отдавать большой ток и может быть пересчитана для измерения других напряжений, например, ±2.5 вольта.
В следующей статье мы рассмотрим ещё несколько способов измерения отрицательного напряжения с помощью АЦП.

hubstub.ru

Работа с АЦП на микроконтроллерах AVR. Измеряем напряжение. Пример на Attiny13 — DRIVE2

Здравствуй, любитель микроконтроллеров!

Полный размер

Готовая плата

Пролог

Давненько я хотел попробовать работать с АЦП на микроконтроллерах AVR. Для меня была интересна возможность реагировать на поднятие напряжения, после того как завелся двигатель автомобиля. Думаю, такая возможность может быть многим полезна. Но чтобы следить за напряжением нужен некий индикатор. И здесь я наткнулся на интересный способ подключения светодиодов у Степан Палыча, да и в книжках по микроконтроллерам этот способ тоже встречается. Придумал эту схему инженер Чарли Аллен в 1995 году и называют ее методом Чарли. Решил попробовать сделать также, печатка получилась довольно похожей.

Схема и алгоритм

Для отладки прошивки набросал схему в протеусе. Сверху светодиод, который мы будем зажигать при поднятии напряжения. Чуть ниже индикатор поднятия напряжения из 6 светодиодов. Ниже для АЦП собран делитель напряжения на резисторах R4 и R5. Чтобы эмитировать изменение напряжения в бортовой сети автомобиля, добавил еще резистор R6, и переменный резистор RV1 — на готовой плате их, конечно же, не будет.

Полный размер

Примерная схема в протеусе

Кроме этого, на схеме не хватает параметрического стабилизатора на резисторе и стабилитроне, который будет питать микроконтроллер. И нет одного конденсатора. Это все есть на макете платы. Здесь хотелось бы отметить, что конденсатор 100n правильнее было бы поставить параллельно резистору R5, а не так как он стоит сейчас. Ну и резисторы на светодиоды индикатора я поставил по 200 Ом (какие уж были), все равно достаточно ярко.

Алгоритм работы будет следующим. При подаче питания первое измерение напряжения с АЦП запоминается и далее следующие замеры сравниваются с ним. Пока напряжение не поднялось горит первый светодиод индикатора. Как только напряжение поднялось на 0.25В, то загорается второй светодиод. Поднялось на 0.5В — загорается третий и т.д. Т.е. шакала деления индикатора — 0.25В. Для нашей задачи этого достаточно. При поднятии напряжения минимум на 0.5В, мы реагируем на это и включаем верхний светодиод. Да не просто включаем, а подаем ему ШИМ сигнал с эффектом дыхания (Хотел проверить, не будет ли ШИМ давать помехи на АЦП). Если напряжение снижается, то ШИМ сигнал на светодиод отключается. Кстати говоря, исходный код подробно комментировал, если что-то не ясно здесь, станет ясно при чтении комментариев к исходному коду.

Чтобы не было совсем скучно, добавил анимацию индикатора поднятия напряжения каждые 10 секунд. Бегущий огонек в сторону повышения и обратно.

Видео работы в автомобиле

А мне нужен индикатор-вольтметр, как сделать?

Да легко и просто, немного подправив прошивку. А если еще освободить ногу контроллера, на которую мы подаем ШИМ сигнал, и использовать ее в индикаторе, то мы получим целых 12 светодиодов вместо 6! При реализации вольтметра стоит посмотреть: достаточно ли точно держит напряжение стабилизации стабилитрон при изменении температуры или же стоит заменить параметрический стабилизатор на что-то другое.

Исходный код, прошивку, модель в протеусе, макет платы можете скачать здесь.

Копия этого поста в сообществе электронных поделок

Желаю творческих успехов!

www.drive2.ru

Измерение напряжения питания микроконтроллера | RadioLaba.ru

            #include <P16F676.INC>

            LIST        p=16F676  

            __CONFIG    b’11111110000100′   ;Конфигурация микроконтроллера

                                              

            

Sec           equ         20h               ;регистры хранения временных данных для

Sec1          equ         21h               ;подпрограмм паузы

Sec2          equ         22h               ;

varLL         equ         24h               ;вспомогательные регистры подпрограммы

varLH         equ         25h               ;деления чисел

tmpLL         equ         26h               ;

rezLL         equ         2Dh               ;

rezLH         equ         2Eh               ;

shet          equ         23h               ;вспомогательные регистры подпрограммы

bcd1          equ         27h               ;преобразования двоичного числа в

bcd2          equ         28h               ;десятичное по разрядам

bcd3          equ         29h               ;

sotni         equ         2Ah               ;

desiat        equ         2Bh               ;

edin          equ         2Ch               ;

 

adr_ind       equ         30h               ;вспомогательные регистры для передачи

dat_ind       equ         31h               ;данных на цифровой индикатор

scetbit       equ         32h               ;

 

#DEFINE       acp_on      PORTA,2           ;линия включения источника опорного напряжения

#DEFINE       datai       PORTC,2           ;линия входа данных драйвера MAX7219

#DEFINE       cs          PORTC,1           ;линия выбора драйвера MAX7219

#DEFINE       clk         PORTC,0           ;линия тактирования драйвера MAX7219

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

              org         0000h             ;начать выполнение программы с адреса 0000h

              goto        Start             ;переход на метку Start

          

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Основная программа

                                              

Start         movlw       b’00000000′       ;Настройка выходных защелок порта A

              movwf       PORTA             ;

              movlw       b’00000010′       ;Настройка выходных защелок порта С

              movwf       PORTC             ;

              

              movlw       b’00000111′       ;выключение компараторов

              movwf       CMCON             ;

 

              bsf         STATUS,RP0        ;выбрать 1-й банк    

              movlw       b’11111011′       ;настройка линий ввода\вывода порта

              movwf       TRISA             ;

              movlw       b’11111000′       ;настройка линий ввода\вывода порта

              movwf       TRISC             ;

              movlw       b’01010000′       ;настройка времени преобразования АЦП (Fosc/16 = 4 мкс)

              movwf       ADCON1            ;

              movlw       b’00000001′       ;Настройка аналоговых/цифровых входов

              movwf       ANSEL             ;RA0 — аналоговый вход

              bcf         STATUS,RP0        ;выбрать 0-й банк  

 

              movlw       b’00000000′       ;Настройка модуля АЦП, канал AN0, левое выравнивание,

              movwf       ADCON0            ;источник опорного напряжения АЦП от линии питания

 

              call        init_lcd          ;вызов подпрограммы инициализации цифрового индикатора

 

Start_1       call        battery           ;вызов подпрограммы измерения и расчета величины напряжения

              call        vivod             ;вызов пожпрограммы вывода значения напряжения на индикаторы

              call        pause             ;вызов подпрограммы паузы 2 секунды

              goto        Start_1           ;переход на метку Start_1

 

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

vivod         movlw       0x08              ;очистка 8-го индикатора

              movwf       adr_ind           ;

              movlw       0x0F              ;

              movwf       dat_ind           ;

              call        send              ;

              movlw       0x07              ;очистка 7-го индикатора

              movwf       adr_ind           ;

              movlw       0x0F              ;

              movwf       dat_ind           ;

              call        send              ;

              movlw       0x06              ;очистка 6-го индикатора

              movwf       adr_ind           ;

              movlw       0x0F              ;

              movwf       dat_ind           ;

              call        send              ;

              movlw       0x05              ;очистка 5-го индикатора

              movwf       adr_ind           ;

              movlw       0x0F              ;

              movwf       dat_ind           ;

              call        send              ;

              movlw       0x04              ;очистка 4-го индикатора

              movwf       adr_ind           ;

              movlw       0x0F              ;

              movwf       dat_ind           ;

              call        send              ;

 

              movlw       0x03              ;вывод значения регистра sotni на 3-й индикатор

              movwf       adr_ind           ;целая часть величины напряжения

              movf        sotni,W           ;

              movwf       dat_ind           ;

              bsf         dat_ind,7         ;установка десятичного знака

              call        send              ;

              movlw       0x02              ;вывод значения регистра desiat на 2-й индикатор

              movwf       adr_ind           ;дробная часть величины напряжения, первая цифра

              movf        desiat,W          ;после запятой

              movwf       dat_ind           ;

              call        send              ;

              movlw       0x01              ;вывод значения регистра edin на 1-й индикатор

              movwf       adr_ind           ;дробная часть величины напряжения, вторая цифра

              movf        edin,W            ;после запятой

              movwf       dat_ind           ;

              call        send              ;

              return

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

battery       bsf         acp_on            ;включение источника опорного напряжения (TL431)

              bsf         ADCON0,ADON       ;включение модуля АЦП

              call        pause             ;вызов подпрограммы паузы 2 секунды

              bsf         ADCON0,GO_DONE    ;установка бита GO_DONE, запуск преобразования АЦП

      

batt_1        btfsc       ADCON0,GO_DONE    ;опрос бита GO_DONE

              goto        batt_1            ;бит GO_DONE не равен 0, преобразование не

                                            ;закончено, переход на метку batt_1

              movf        ADRESH,W          ;преобразование закончено, копирование значения

              movwf       tmpLL             ;в регистр tmpLL

 

              bcf         acp_on            ;выключение источника опорного напряжения (TL431)

              bcf         ADCON0,ADON       ;выключение модуля АЦП

 

              movlw       .7                ;запись числа 62475 в регистры varLH, varLL для

              movwf       varLL             ;последующего деления

              movlw       .248              ;

              movwf       varLH             ;

              call        del               ;вызов подпрограммы деления числа 62475 на результат преобразования АЦП

              call        bin2bcd           ;вызов подпрограммы преобразования двоичного числа в десятичное по разрядам

              return                        ;выход из подпрограммы

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Подпрограмма деления двухбайтного числа на однобайтное (varLH, varLL):(tmpLL)

;Результат деления в регистре rezLH, rezLL, деление целочисленное без дробной части

;на ноль делить нельзя, произойдет выход из подпрограммы без изменений

 

del           clrf         rezLL            ;очистка регистров rezLL, rezLH (эквивалентно записи нуля)

              clrf         rezLH            ;

              movlw        .0               ;проверка равенства нулю числа лежащего в регистре tmpLL

              xorwf        tmpLL,W          ;(на ноль делить нельзя)

              btfsc        STATUS,Z         ;

              return                        ;число в регистре tmpLL равно нулю: выход из подпрограммы

                                            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

d1            movf         tmpLL,W          ;число в tmpLL не равно нулю: вычитаем число лежащее в регистре

              subwf        varLL,F          ;tmpLL из числа в регистрах varLH, varLL: это операция вычитания

              btfsc        STATUS,C         ;однобайтного числа из двухбайтного

              goto         d2               ;при отрицательном результате происходит выход из подпрограммы

              movlw        .1               ;при положительном результате инкрементируем счетчик вычитаний

              subwf        varLH,F          ;переходя на метку d2

              btfss        STATUS,C         ;

              return                        ;

                                            ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

d2            incfsz       rezLL,F          ;инкремент rezLL с проверкой на переполнение      

              goto         d1               ;нет переполнения rezLL: переход на метку d1

              incf         rezLH,F          ;переполнение rezLL: инкремент регистра rezLH (регистры rezLL, rezLH  

                                            ;выступают в качестве счетчика вычитания и содержат результат деления)

              goto         d1               ;переход на метку d1 для повторного вычитания, операция деления

                                            ;представляет собой многократное вычитание

                                          

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                            

 

bin2bcd       movlw       .16               ;Подпрограмма преобразования двоичного числа

              movwf       shet              ;в десятичное

              clrf        bcd1              ;Двухбайтное число предварительно загружается

              clrf        bcd2              ;в регисты rezLH, rezLL

              clrf        bcd3              ;Результат преобразования:

              goto        bin2bcd_1         ;единицы в младшем полубайте bcd3

                                            ;десятки в старшем полубайте bcd3

adjdec        movlw       0x33              ;сотни в младшем полубайте bcd2

              addwf       bcd1,F            ;тысячи в старшем полубайте bcd2

              addwf       bcd2,F            ;десятки тысяч в младшем полубайте bcd1

              addwf       bcd3,F            ;

                                            ;

              movlw       0x03              ;

              btfss       bcd1,3            ;

              subwf       bcd1,F            ;

              btfss       bcd2,3            ;

              subwf       bcd2,F            ;

              btfss       bcd3,3            ;

              subwf       bcd3,F            ;

                                            ;

              movlw       0x30              ;

              btfss       bcd1,7            ;

              subwf       bcd1,F            ;

              btfss       bcd2,7            ;

              subwf       bcd2,F            ;

              btfss       bcd3,7            ;

              subwf       bcd3,F            ;

                                            ;

bin2bcd_1     rlf         rezLL,F           ;

              rlf         rezLH,F           ;

              rlf         bcd3,F            ;

              rlf         bcd2,F            ;

              rlf         bcd1,F            ;

              decfsz      shet,F            ;

              goto        adjdec            ;

                                            ;

              movf        bcd3,W            ;копирование значения единиц из младшего

              andlw       b’00001111′       ;полубайта bcd3 в регистр edin

              movwf       edin              ;

              

              swapf       bcd3,W            ;копирование значения десятков из старшего

              andlw       b’00001111′       ;полубайта bcd3 в регистр desiat

              movwf       desiat            ;

 

              movf        bcd2,W            ;копирование значения сотен из младшего

              andlw       b’00001111′       ;полубайта bcd2 в регистр sotni

              movwf       sotni             ;

              return                        ;выход из подпрограммы

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Подпрограмма инициализации драйвера(MAX7219) цифрового табло

 

init_lcd      call        pauslcd           ;вызов подпрограммы паузы 2 мс

              movlw       0x0F              ;выключить тестовый режим

              movwf       adr_ind           ;

              movlw       0x00              ;

              movwf       dat_ind           ;

              call        send              ;

 

              movlw       0x0C              ;включение индикатора

              movwf       adr_ind           ;

              movlw       0x01              ;

              movwf       dat_ind           ;

              call        send              ;

 

              movlw       0x0A              ;интенсивность 15/32

              movwf       adr_ind           ;

              movlw       0x07              ;

              movwf       dat_ind           ;

              call        send              ;

 

              movlw       0x09              ;использовать BCD Code B для всех индикаторов

              movwf       adr_ind           ;

              movlw       0xFF              ;

              movwf       dat_ind           ;

              call        send              ;

 

              movlw       0x0B              ;использовать 8 индикаторов

              movwf       adr_ind           ;

              movlw       0x07              ;

              movwf       dat_ind           ;

              call        send              ;

              return                        ;выход из подпрограммы

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Подпрограмма отправки 2-х байт на драйвер (MAX7219) цифрового табло по пртоколу SPI

 

send          bcf         cs                ;Сбросить линию выбора драйвера CS

              movlw      .8                 ;Отправка содержимого адресного байта adr_ind

              movwf      scetbit            ;

povtor        bcf        clk                ;

              btfsc      adr_ind,7          ;

              bsf        datai              ;

              btfss      adr_ind,7          ;

              bcf        datai              ;

              bsf        clk                ;

              rlf        adr_ind,F          ;

              decfsz     scetbit,F          ;

              goto       povtor             ;

            

              movlw      .8                 ;Отправка содержимого байта данных dat_ind

              movwf      scetbit            ;

povtr1        bcf        clk                ;

              btfsc      dat_ind,7          ;

              bsf        datai              ;

              btfss      dat_ind,7          ;

              bcf        datai              ;

              bsf        clk                ;

              rlf        dat_ind,F          ;

              decfsz     scetbit,F          ;

              goto       povtr1             ;

              bcf        clk                ;

              bsf        cs                 ;установить в 1 линию выбора драйвера CS                

              return                        ;выход из подпрограммы

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

 

pauslcd       movlw       .4                ;подпрограмма пауза 2 мс

              movwf       Sec1              ;

p_l2          movlw       .166              ;

              movwf       Sec               ;

p_l1          decfsz      Sec,F             ;

              goto        p_l1              ;

              decfsz      Sec1,F            ;

              goto        p_l2              ;

              return                        ;выход из подпрограммы

 

pause         movlw       .11               ;

              movwf       Sec2              ;

p_3           movlw       .255              ;подпрограмма пауза 2 сек

              movwf       Sec1              ;

p_1           movlw       .255              ;

              movwf       Sec               ;

p_2           decfsz      Sec,F             ;

              goto        p_2               ;

              decfsz      Sec1,F            ;

              goto        p_1               ;

              decfsz      Sec2,F            ;

              goto        p_3               ;

              return                        ;выход из подпрограммы

                          

              end                           ;конец всей программы

                                            ;

radiolaba.ru

Как измерить отрицательное напряжение с помощью АЦП, продолжение… » Хабстаб

В прошлой статье мы рассмотрели несколько способов измерения отрицательного напряжения с помощью АЦП, в этой предлагаю рассмотреть ещё несколько способов, которые заслуживают внимания. Один из них можно увидеть в популярном сейчас конструкторе DSO138.

Как видно, в этой схеме не используется сумматор, но принцип работы схемы тот же, что описан в прошлой статье. Давайте вспомним его, необходимо задать смещение, равное половине динамического диапазона АЦП(в данном случае от 0 до 3.2), то есть когда на вход ОУ приходит 0 вольт, на выходе должно быть 1.6 вольта(это можно увидеть на схеме, пометка с двумя звёздочками). Дальше разработчики сделали так, по крайней мере, похоже на то, когда на вход ОУ приходит -0.8 вольта на выходе 0,07 вольта, а когда приходит 0.8 вольта, на выходе 3.27 вольта. В таком случае динамический диапазон АЦП составляет 3.2 вольта и видно, что напряжение 1.6 вольта не является его серединой, но для нас это не принципиально, нас больше интересует данный способ измерения.

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

Пусть на прямой вход приходит 0 вольт, тогда на инвертирующем должно быть столько же, на выходе ОУ будет 1.6 вольта. В таком случае ток через R11 не течёт, нет разности потенциалов. Получается, что ноль на инвертирующем входе формирует делитель напряжения образованный R9 и R10.

На схеме видно, что падение напряжения на R10 в 3.125 раза больше чем падение на R9, так как резисторы соединены последовательно, следовательно их сопротивления относятся примерно как R10/R9 = 3/1. Предположим, что R9 = 1K, а R10 = 3K.

Пусть на прямой вход ОУ приходит 0,8 вольта, на инверсном будет столько же, а на выходе ОУ будет 3.27 вольта. На R9 в такой ситуации будет падать 2.47 вольта и протекать ток равный 2.47mA.

Дальше этот ток разделится и потечёт через R10 и R11.

Давайте рассмотрим какой ток будет протекать через R10.

I10 = (0.8 — (-5))/3000 = 1.93mA

Ток протекающий через R11 равен разности токов через R9 и R10.

I11 = 2.47 — 1.93 = 0.54mA

Разделим 0.8 вольта на 0.54mA и получим номинал R11

R11 = 0.8/0.54 = 1.48K

Смотрим на схему и видим, что полученное значение немного отличается от действительного(1.5K), одна из причин этому то, что мы не учитывали напряжение смещения ОУ.


Давайте промоделируем схему в микрокапе при разных входных напряжениях.

Картинки выше подтверждают расчёты, единственной загадкой остаётся, почему в схеме пишут, что при подаче 0 вольт на вход ОУ, на его выходе будет 1.6 вольта.

P.S По ходу вычислений было сделано два приближения, первое — то что R10/R9 = 3, хотя у нас получилось 3.125, второе — то что при расчётах не было учтено напряжение смещения ОУ. В общем такой результат нельзя назвать положительным, поэтому попросил знакомого, у которого есть DSO138 , что бы он измерил напряжение на выходе ОУ в режиме GND(ну не может быть там 1.6 вольта думал я). И действительно, в режиме GND на выходе ОУ оказалось 1.67 вольта и это всё ставит на свои места. Исправлять расчёты в статье не буду, но каждый желающий может сделать это самостоятельно, так как теперь знает методику расчёта.

hubstub.ru

Измерение аналоговых величин микроконтроллером, на практике. Часть 1 — radiohlam.ru

Предисловие

В былые, доцифровые времена любому из нас приходилось довольствоваться стрелочными измерительными приборами, начиная от обыденных часов, весов и заканчивая… хм, так вот сразу даже и не найти границу их применения! Ну, скажем – прецизионный лабораторный микро- или еще внушительнее – пикоамперметр. И классов точности их тоже имелось достаточно много, в зависимости от назначения.

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

Зато в лабораториях, особенно в Госповерке, имелись стрелочники с зеркальной шкалой и класом точности много лучше 0,5.

И практически все из нас были довольны и счастливы. А если не были довольны, то приобретали более точные приборы, конечно по-возможности!

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

Путь от измеряемой величины к индикатору

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

Для начала я выбираю силу тока!

Мне придется повторить банальность, что для получения цифрового представления аналоговой величины необходим аналогово-цифровой преобразователь (АЦП). Но поскольку сам по себе он нам еще мало пригоден, то понадобятся и другие узлы для завершения всего задуманного. А именно:

  1. перед самим АЦП нужно нормирующее устройство, скажем: нормирующий усилитель или ослабитель, в зависимости от соотношения входной величины к диапазону преобразования АЦП;
  2. декодер после АЦП, для представления преобразованного числового эквивалента в цифровой код соответствующего индикатора.

Существуют готовые микросхемы, объединяющие в себе и АЦП и декодер. Например, ICL7136 или подобные, применяемые в мультиметрах.

По существу, все эти узлы в том или ином виде просто необходимы. Я еще не назвал самого датчика – в данном случае – преобразователь тока в напряжение, или просто шунт.

Итак, пробежимся вкратце по всей цепочке. Ток, протекающий через шунт (мощный резистор с очень низким сопротивлением), создает на его полюсах разность потенциалов. Guten Tag, Herr Ohm! Но эта разность довольно мала и не каждый АЦП способен эту величину в полной мере преобразовать, поэтому сигнал (напряжение) с шунта необходимо усилить до приемлемой величины. Для этого и нужен нормирующий усилитель. Теперь АЦП, получив на вход удобоперевариваемое напряжение, выполнит преобразование с минимально возможной погрешностью. На выходе из него получим число, соответствующее текущему значению измеренного тока в выбранном диапазоне, которое для вывода на индикатор нужно соответствующим образом декодировать. К примеру, преобразовать в код семисегментного индикатора.

Здесь я не вижу необходимости более подробно останавливаться на каждом из приведенных этапов, поскольку в статье я преследую иную цель. А подробности найдутся в интернете с избытком.

Конкретика

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

Мой встроенный амперметр собран и запрограммирован на МК Tiny26L. Частью этого амперметра является второй (свободный) ОУ микросхемы LM358, входящей в составбазовой схемы балласта. Т.е. это мой нормирующий усилитель, поскольку максимальное падение напряжения на шунте (5 А х 0,1 ом) составляет всего 0,5 вольта, что явно недостаточно для полного диапазона преобразования с внутренним опорным напряжением.

Согласно Т.О. (англ.= Datasheet) номинальное напряжение встроенного опорного источника (ИОН) составляет 2,56 вольта. Очень удобная величина! Однако, на практике получается не так уж и здорово: выверенное напряжение ИОН-а моего МК оказалось 2,86 вольта! Каким образом я это определил – отдельная тема. Давайте все-таки вернемся к удобным 2,56 вольтам. Смотрите, что получается: на шунте падает максимально 0,5 вольта, АЦП преобразует максимально 2,56 вольта. Напрашивается нормирующий усилитель с коэффициентом усиления 5, тогда и полученное при преобразовании число не потребует какой-либо развитой арифметики для представления результата: 5 ампер = 2,5 вольта = 250 единиц (для 8-битного преобразования). Придется всего лишь умножить результат на два и поставить десятичную точку между сотнями и десятками, чтобы получить совсем удобное представление: единицы, десятые и сотые доли ампера. Конечное преобразование в семисегментные знаки – дело техники. Всё прекрасно, можно воплощать в «железо»!

Однако, как я уже показал на примере встроенного ИОН-а, приемлемой (я уже не говорю – высокой!) точности на используемых компонентах получить так легко не получится. Можно пойти по пути компенсации погрешностей математически, с помощью программы в МК, хотя для этого придется производить градуировку. Этот путь довольно просто реализуется на Си и других языках высокого уровня. Но мне, упертому ассемблерщику, разводить математику инструкциями RISC – лишняя головная боль!

Я выбрал другой путь, — коррекцию коеффициента усиления нормирующего усилителя (НУ). Много для этого не потребуется – один подстроечный резистор! Значение его нужно правильно выбрать, чтобы диапазон подстройки был достаточным, но не преувеличенным.

Подбор элементов нормирующего усилителя

Итак, необходимо определить диапазон подстройки. Первым делом нужно определиться с допусками компонентов. Например, мой шунт имеет допустимую погрешность 1%. Прочие резисторы в схеме нормирующего усилителя могут имеют допуск до10%. И не забываем неточность нашего ИОН-а, которая составила в моем случае почти +12%! Это значит, что реально преобразованное число будет меньше почти на 12%. Но поскольку эта погрешность у меня уже известна, то я учитываю ее в коэффициенте усиления НУ, который должен составить 5,72. А поскольку реальные погрешности прочих компонентов не известны, то остается найти максимально возможную суммарную погрешность, чтобы расчитать диапазон подстройки.

Напрашивается простая сумма этих вот «процентов»: 1% шунта плюс 2 раза по 10% резистороров обратной связи ОУ. Итого: 21%.

Посмотрим, так ли это на самом деле. Для этого взглянем на часть схемы, где представлен этот НУ с уже подобранными номиналами:

Как видно, имеет место неинвертирующий усилитель с перестраиваемым коэффициентом передачи, теоретически регулируемым от 4,979 до 6,735 при указанных на схеме номиналах. Но, если учесть наши ±10% возможной погрешности каждого из резисторов, то получим при найхудшем сочетании Ку = 5,864 – 8,009 , что явно превышает необходимый коэффициент! Если это сочетание будет иметь место, то придется взять другие номиналы. А лучше сразу увеличить номинал подстроечного резистора, например, до 39к. Тогда нижняя граница Ку будет 5,454 , что уже приемлемо.

Ну, мне – «настоящему радиохламеру» — пришлось выбирать подстроечник из того, что было, и просто повезло вложиться в диапазон! Был бы подстроечник другого номинала – не беда, пересчитал бы R2 и R3, которые в моем случае имеют допуск 5%, поэтому мне не пришлось брать другой подстроечник.

Преодоление своих недочетов и упущений

Казалось бы, всё продумано и расчитано – разводи плату. А давай-ка испытаем эту конструкцию сперва на макетке! Сказано – сделано! Ку перестраивается не совсем как ожидалось, но в пределах необходимого. Однако индикатор не собирался показывать 0.00 при отсутствии тока нагрузки! Первым делом я заподозрил программу в МК, но при закорачивании входа АЦП на общий провод заветные нолики появлялись. Значит, что-то таки приходит на вход МК, отличное от нуля вольт. Проверка мультиметром подтвердила это предположение и поставила очередную задачу. Не вдаваясь в подробности моих изысканий, опишу лишь их результат.

Причина оказалась в следующем: я совершенно не учел, что примененный мною ОУ далеко не лучшего качества. Он даже не т.н. «rail-to-rail». Это означает, что его выходной потенциал никогда не достигнет ни одного из полюсов питания, т.е. в моем случае никогда не будет равен 0 вольт! Вот если бы он питался от двуполярного источника, тогда бы на выходе получился ожидаемый ноль. Но у меня источник питания однополярный и усложнять схему каким-либо преобразователем я не намеревался. Выход был найден в создании «виртуальной земли», т.е. благодаря отдельному источнику питания (в отличие от базовой схемы) мне удалось с помошью диода сдвинуть потенциал общего провода относительно минусового полюса батареи.

Итак, плата вытравлена и спаяна. Пора бы эту конструкцию упаковать в корпус. Что, собственно, и было сделано. Однако, во время эксплуатации вылез еще один маленький недочет – дрейф входных цепей ОУ. Это выражалось в отрицательном сдвиге показаний, т.е. при токе в пару десятков миллиампер на индикаторе по-прежнему были нули, что меня не устраивало! Я бы допустил сдвиг в несколько мА – все равно единицы миллиампер не отображаются. Пришлось вводить схему смещения на вход НУ.

Номиналы R4 и RZ подобраны так, что бы обеспечить смещение плюс/минус несколько десятков милливольт относительно «виртуальной земли». У меня не было желания переделывать готовую плату и я довесил необходимый подстраиваемый делитель на место подстроечника Ку.

В общем и целом получившийся приборчик удовлетворяет мои потребности. Усовершенствовать его, конечно же, можно еще долго, но пока нет необходимости!

О цифровой части и математике я расскажу в следующий раз на примере вольт-амперметра лабораторного блока питания.

продолжение…

radiohlam.ru

Замер сетевого напряжения | Электроника для всех

Иногда нужно измерять амплитуду сетевого напряжения, или частоту или еще какие параметры. Вот как у меня тут — перед включением компрессорной установки надо убедиться, что напряжение в сети не ниже номинальной. Иначе движок не стартанет, а вентили могут не встать в нужное положение. Главная сложность тут в том, что крайне желательно иметь гальваническую развязку от сетевого напряжения. Т.е. напрямую измерять сетевую напругу через простой делитель может быть черевато.

▌Измерить толщину сиськи
Изначально в проекте было заложено вот такое решение:

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

Ну, а дальше все просто. У оптопары h21L1M внутри стоит триггер Шмитта, т.е. есть некоторый гистерезис на включение и выключение. Включается он при токе через его светодиод примерно в 1мА, а выключается на токе 0.8мА.

Если посмотреть осциллограмму тока на светодиоде, сняв ее с резистора R35, то увидим такую картину для 220 вольт:


Разрешение 50мВ на деление, триггер стоит на 80мВ по спаду.

Включаться он должен на 100мВ, а выключаться на 80мВ, что будет 1мА и 0.8мА соответственно. Курсорами выделены моменты включения и выключения. Разница по времени, dx = 8.38ms

Если снизить напряжение до 110 вольт, то:

dx уменьшится до 6.94ms т.е. А что такое миллисекунда для микроконтроллера тикающего на мегагерцовых частотах? Да колоссальная величина! Замерить ее точно таймером в режие захвата не составляет проблем. Дальше сунуть в память таблицу соответствия и, казалось бы, все круто? Да, но не совсем…

Решение дешевое, простое. Но не слишком точное. А в ряде случаев его вообще не получится применить.

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

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

Так что 220 вольт от 110 вы еще отличите, а вот о точности хотя бы до 5 вольт можно позабыть. Но в некоторых случаях большего и не требуется.

Мне же внезапно потребовалось. Поэтому начинаем переделывать исходный проект, доставшийся мне от предшественника.

Первая мысль была поставить на горячей стороне преобразователь напряжения в частоту, просунув его через ту же оптопару. Но его надо было чем то питать на горячей стороне. Ставить конденсаторный источник вообще не хотелось. Можно было бы, конечно, сунуть мелкий модуль 220AC-5DC на обратноходовике, вроде TSP-05. Есть на Али, стоит недорого.

Надо на этот модуль обзор не полениться сделать. Классная штука для питания всякой маломощной шняги от 220 вольт. Но получалось бы довольно громоздко. Считай питальник, потом ПНЧ, оптика…

▌Трансформатор
Второй мыслью был обычный трансформатор. Купить самый маленький силовой транс какой можно найти и на вторичке измерять напряжение. Спросил у Элемента, что у них есть такого рода — подобрали ТПК-2.

В принципе пригодно, но нашлось решение лучше.

Китаезы продают отличную штуку. Измерительный трансформатор ZMPT107.

Крошечная фитюлька размером с бульонный кубик. Держит до 3кВ на пробой, соотношение витков 1:1, но это трансформатор тока 2мА:2мА. То есть мы подаем ему на вход ток и снимаем ток. Ток на входе задается просто резистором последовательно, а для получения напряжения на выходе тоже применяется резистор, параллельно.

Т.е. схема примерно выглядит так:

R1 подбирается таким, чтобы ток через обмотку не превысил 2мА, максимум он держит 10мА, но после 2мА теряется линейность и на выходе будет невесть что. Напряжение у нас 220-250 вольт, берем по верхней планке. Но это действующее, а нам нужно амплитудное. Т.е. умножаем 250 на корень из 2, чтобы получить амплитудное. 250*1.41 = 353,5 вольта. Получаем, что первое сопротивление должно быть 180 кОм.

Напряжение микроконтроллера у меня 5 вольт, поэтому резистор R2 нужен такой, чтобы на 2мА на нем было примерно 4.5 вольта, пол вольта оставляем еще в запас. Это будет примерно 2.2кОм.

Все, на выходе амплитуда теперь в районе 5 вольт, но вот засада. Она переменная. А нам нужны измерения 0…5 вольт. Что делать? Выпрямлять.

▌Дайте мне диод!

Можно поставить диод, он срежет отрицательную полуволну. Но тут есть одна тонкость. Если просто в лоб поставить диод перед нагрузочным резистором:

То на обратной полуволне получается, что мы будем обрывать трансформатор тока, а что получается при обрыве источника тока? Правильно — бешеное напряжение. Ведь он будет изо всех сил пытаться продавить свои 2мА через ОГРОМНОЕ обратное сопротивление диода. В результате на диоде D1 высадится такое напряжение, что и пробить недолго. В таком включении ставить только мост или обратный диод D2, чтобы у тока всегда были пути на обратной полуволне.

Но это будет уже два диода. А зачем нам лишний полупроводник в схеме? Поэтому проще оставить параллельный резистор и после выпрямлять уже снятое напряжение.

Чтобы система работала, нужен еще один резистор. Дело в том, что у АЦП входное сопротивление ну очень большое, сравнимое с обратным включением диода, так что диод работать не будет, ему надо чтобы ток шел. Поэтому ставим второй резюк на 100кОм и с него уже снимаем наш сигнал.

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

Смотрите внимательней, синий это исходный синус с транса, а желтый это положительная полуволна с диода. От нулевой точки синус идет как и положено синусу, а вот диодная полуволна нарастает с заметной такой экспоненциальной кривизной и не доходит на величину падения на диоде (0.7 вольт примерно для 1N4148, что стоит у меня).

Экспонента берется из ВАХ диода

Мне, в моем проекте, это не сильно критично. НУ будет там возле нуля какая то кривуля, не важно.

▌Ваш диод говно, вы за кого меня принимаете? Дайте мне идеальный диод!
Но если бы было критично, то я бы сгородил идеальный диод. Делается он из диода и операционника. Схем много разных, первая что пришла в голову была такой.

Работает она просто.

Усилитель с отрицательной обратной связью, так что считаем что его входы закорочены между собой (виртуальное КЗ).

На положительной полуволне ток Iin=Uвх/R3 со входа как бы течет в землю через резистор R3. Но поскольку на самом деле никакого КЗ там нет, более того через входы ОУ ничего не втекает и не вытекает (ну почти, там ничтожный мизер в реале). То ток текущий через R3 равный Iin будет совершенно равен Iout который из выхода ОУ течет через R3 в землю. Образуя падение напряжения Uвых прямо пропорционально этому току через резистор. Т.е. Uвых = Iin*R3 = Uвх Без каких либо искажений.

На отрицательной полуволне ОУ попытается через обратную связь просадить свой инверсный выход ниже нуля, чтобы сравнять его с прямым. Но диод забитый туда не даст ему это сделать. Через R3 не потечет ток, а нет тока нет и напряжения. На выходе 0.

Вот такая вот незатейливая схема. Работает на двуполярном и однополярном питании.

Единственное, что для однополярного питания нужно брать усилок во-первых, строго однополярного питания (Single-supply) при этом способный принимать отрицательные значения на входах (Input Common-Mode Voltage Range), а во-вторых, с rail-2-rail выходом, иначе посрезает верхушки.

Т.е. ширпотреб вроде LM358 не прокатит, а что то вроде AD823 в самый раз. Для двуполярного питания же подойдет любой ширпотреб, ну может rail-2-rail будет не лишним, но опять же от напряжения питания зависит и требуемых уровней. Если не нужен полный размах от плюса до минуса питания, то ставим любое говно за три копейки и не паримся.

▌Нет! Засуньте вы этот диод знаете куда…

Второй вариант включения, немного получше, нет диода:

Тут включается напрямую в операционник. Соотношение резисторов точно такое же как и в первом варианте. Трансформатор закорачивается на виртуальную землю, а ток который там течет течет через резистор ОС. Но так как у нас питание однополярное, то нижняя полуволна просто зарывается в грунт. Требования к операционнику те же самые, что и в прошлой схеме. Rail-2-Rail и Single Supply.

▌Эй эй, зачем столько негатива? Будь на позитиве, бро!
Ну и третий вариант включения. Тут даже операционник не нужен, мы не выпрямляем и не срезаем нижнюю полуволну, а добавляем к ней постоянную составляющую. Закинув наш транс на середину делителя напряжения. Резистор на вторичке надо подобрать так, чтобы амплитуда не вылезала за напряжение питания и не проваливалась ниже его.

Результат выглядит примерно так:

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

▌А что Титов Китай?
Ну и для всяких ардуинщиков, не умеющих паять, есть готовый модуль.

Там же не али можно взять. Стоит не дорого, на нем схема с поднятием нуля на LM358 и можно еще амплитуду подкрутить переменником. Схемотехника там примерно следующая:

Но это не точно.

Вот что он выдает у меня в мастерской с сети:

Когда сети нет, то на выходе постоянка в 2.5 вольта. А появление сети дает вот такую синусоиду с центром 2.5 и размахом от 1 до 4 вольт. Подстроечником можно менять амплитуду сигнала, но это вот максимум. Выше уже начинаются искажения — срезает вершину.

И библотечка дуриковсякая для него на гитхабе.

Вот такие вот относительно простые варианты замерить сеть и не потерять гальваническую развязку.

easyelectronics.ru

0 comments on “Измерение отрицательного напряжения микроконтроллером – Как измерить отрицательное напряжение с помощью АЦП. » Хабстаб

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *