Измерение тока STM32 АЦП HAL (шунт, дифференциальный усилитель)

Принцип работы (измерения)

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

Таким образом протекающий ток через Rload и Rsense будет одинаковый (здесь 690 мА), при этом зная сопротивление резистора-шунта Rsense = 0.1 Ом и измерив напряжение на нем (Usense = 0.069 В) можно легко вычислить протекающий через цепь ток:

I = Usense/Rshunt0.069/0.1 = 0.69 А = 690 мА

А теперь испытания на макетной плате, лампа накала в качестве нагрузки Rload (ИСКРА 13,5 В), низкоомный резистор Rsense 3.3 Ом 10 Вт.

Берем вольтметр и измеряем напряжение на резисторе.

Итак, падение на нем Usense = 0.2757 В. Вычисляем ток

I = Usense/Rshunt = 0.2757/3.3 = 0.08354 А = 83.54 мА

Учитывая неточность резистора, всё отлично, почти такой же, как показывает мультиметр ( ламповый блок питания показывает неправильно!).

Выбор шунта

  • малое сопротивление (чтобы уменьшить потери и вносимое влияние)
  • высокая точность сопротивления
  • малый ТКС (чтобы сопротивление мало изменялось при изменении температуры)

Схема

Понятно, что при маленьком значении сопротивления Rsense будет падать и маленькое напряжение, а нам его еще и измерять, причем мы хотим получить диапазон от нуля то VCC (в данном случае от 0 В до 3.3 В), чтобы использовать все 12 разрядов внутреннего АЦП STM32.

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

Таким образом нам удастся усилить маленькое напряжение на Rsense, а напряжение на выходе будет определятся соотношениями сопротивления резисторов, при R1 = R3, R2 = R4:

U1 - напряжение на инвертирующем входе;
U1 - напряжение на неинвертирующем входе;
R2=R4 - сопротивление резистора;
R1=R3 - сопротивление резистора;

Выбор операционного усилителя

Нам нужен ОУ с низким напряжением питания (т.к. он будет жить вместе с МК на стабилизаторе 3.3 В), маленьким входным напряжением смещения (input offset voltage) и маленьким (как можно ближе к нулю) выходным напряжением низкого уровня.

LMV321

Смотрим на эту гадость, ну такое.

Проверим в бою. На входе Usense = 100 мВ (падение на шунте):

При R1 = R3 = 1 кОм, R2 = R4 = 10 кОм, допуск резисторов 1% (также отобрал вручную самые точные), таким образом на выходе должно быть  Usense*10 = 100 мВ*10 = 1000 мВ = 1 В (выражение выше):

Хорошо, усиление в 10 раз сработало отлично!

Помня про высокое значение выходного напряжения низкого уровня замыкаем шунт (на входе ноль), а на выходе:

Ой, нифига себе, примерно 80 мВ (собственно как и написано в документации). Нам такого не нужно, ведь тогда не удастся измерять малые токи.

Но, выходное напряжение высокого уровня действительно почти равно питающему, то есть чуть ниже 3.3В и по сути будет отличаться на 100 мВ максимум.

LM358

Сравнивая с предыдущим у этого выходное напряжение низкого уровня будет около 5 мВ, вот это уже неплохо.

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

Неплохо, даже ниже обычного, то что нужно!

А теперь проверим выходное напряжение высокого уровня (питание 3.3 В):

И еще раз, но при питании 5 В:

Вот это печально. Выход ниже на более чем вольт по сравнению с напряжением питания, то есть использовать этот ОУ в схемах с низким Uпит не советую, ведь тогда будут полезными (использоваться) не 12 разрядов АЦП, а в данном случае всего чуть более 7-бит!  (исп. от 30.10.2021)

MCP6002

Приобрел ОУ MCP6002 в SOIC-8 от Micropchip.

Здесь выходное напряжение (Voltage Swing) мин 25 мВ, на деле оказалось около 7 мВ, вот эта микросхема и будет использована!

Не забудь добавить фильтр!

Настоятельно советую отфильтровать измеряемый сигнал перед подачей на АЦП простейший фильтр нижних частот (ФНЧ) в виде последовательно соединённых резистора и конденсатора ( как работает можно глянуть здесь). Также дополнительно советую использовать программный цифровой фильтр среднего скользящего.

Для использований общего назначения обычно ставят:

R = 10 - 100 Ом
C = 100 нФ - 1000 нФ

Сборка схемы на макетной плате

Создание проекта в STM32CubeIDE

Новый проект: New -> STM32 Project

Выбор МК: STM32F103C8T6

Имя проекта: Project Name: Current-Measeument-Shunt

Настройки тактирования по умолчанию (ничего не изменено):

Отладчик: SYS -> Debug: Serial Wire

Включение АЦП, Канал 0. Запуск от тригера Таймера 3:
ADC_Regular_ConversionMode: External Trigger Conversion Source

Во вкладке настройки ПДП (DMA):
Add: ADC1
Mode: Circular

Ну и Таймер 3:
TIM3 -> Internal Clock
Prescaler: 800-1
Counter Period: 1000-1
Trigger Event Selection: Update Event

Ну и хватит! 

Программирование

Массив из одного элемента для сырого значения с АЦП и вещественная переменная для напряжения, а также вспомогательная переменная:

/* USER CODE BEGIN PV */ /* adc variables */ uint16_t ADC_Raw[1]; float Current; uint8_t sch_adc = 0; /* USER CODE END PV */

Запуск АЦП с ПДП, ну и потом таймер, который будет производить запуск 10 раз/с:

/* USER CODE BEGIN 2 */ HAL_ADCEx_Calibration_Start(&hadc1); HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_Raw, 1); HAL_TIM_Base_Start_IT(&htim3); /* USER CODE END 2 */

В функции обратного вызова переменная устанавливается равной 255, то есть положительное значение:

/* USER CODE BEGIN 4 */ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle) { sch_adc = 255; } /* USER CODE END 4 */

В главном цикле проверяется переменная sch_adc, если положительная, то рассчитывается значение тока (здесь в мА):

/* USER CODE BEGIN WHILE */ while (1) { if(sch_adc){ Current = ((ADC_Raw[0]/4095.0f))*100; /* Nullify */ sch_adc = 0; } /* USER CODE END WHILE */

Испытание (отладка)

При отсутствии тока на выходе ненулевое значение. Его можно обнулять каждый раз при включении (учитывая что вначале нагрузка не должна быть подключена) или записать значение и потом вычитать из измеренного:

Точность неплохая и может быть лучше, потому что напряжение питание чуть ниже 3.3В и шунт-резистор использован неточный.

Особенности разводки платы

На рисунке ниже видно, что входы дифференциального усилителя хитро подключаются непосредственно к Rsense, ведь нам не нужны еще и падения на дорожках и соединениях.

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

Также здесь стоит обратить внимание на фильтрующий конденсатор 100 нФ, он подключен наиболее близко к ножкам GND-VCC и питание подведено сначала к нему.

Измерения без использования ОУ

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

Примером может служить мой тестер проверяльщик светодиодов, здесь нужно было измерять ток (0-100) мА, сначала хотел ставить шунт+ОУ, но из-за ограниченного напряжения питания и ненулевого выхода при нулевом токе схема была оптимизирована и упрощена вместе с решением проблемы измерения малых токов.

Готовые токоизмерительные усилители

Конечно существуют усилители с уже встроенными резисторами R1-R4, причем они имеет почти одинаковые параметры. К тому же мы экономим место на плате. Коэффициент усиления как-правило 20, 30, 50, но есть и такие, где он настраивается.

Самым подходящим я считаю решение INA180 от TI единственный недостаток - это низкая распространенность, ну и цена будет чутка выше.

Купить на Aliexpress

?️ ОУ MCP6002 SOIC-8 10pcs (0.96?): https://ali.ski/uI4cOl
?️ ОУ MCP6002 DIP-8 10pcs (2.00?): https://ali.ski/AFO9Qp
?️ Плата STM32F103C8T6 (3.87?): https://ali.ski/4FS-nh
?️ Плата STM32F103C8T6 Blue Pill (2.32?): https://ali.ski/5TUQ2J
?️ Плата STM32F030F4P6 Board (1.47?): https://ali.ski/4M_4zP
?️ Плата STM32F030F4P6 48 MHz (1.29?): https://ali.ski/m1Js1
? Мой мультиметр T21D RM113D (15.28?): https://ali.ski/T8fSy

Видос

19850
RSS
Егор
08:37

Супер статья. Как раз собираюсь делать что-то подобное. Есть один вопрос: если неправильно подключить измерительные щупы от АЦП контроллера (перепутать "+" и "-"), он выйдет из строя? Направление течения тока ведь будет противоположное. Может, надо ставить защитный диод? Но на нем будет падение напряжения? Может есть еще варианты? Заранее спасибо за ответ!

22:09

Не должно выйти, там внутри есть защитные диоды.

Поставьте ОУ как дифференциальный усилитель.

20:13

А от высокого напряжения вполне можно убить канал.

У меня получилось напряжением где-то 5В-8В сжечь один из каналов АЦП 

А вам лучше делать измерения тока в двух направлениях. То есть средней точкой будет 1.65В, при одной полярности напряжение будет 1.65В-3.3В, а при обратной 0В-1.65В. Такое легко сделать с помощью микросхемки INAxxx.

timurko
07:27

А почему ты для этих целей взял именно MCP6002, а не MCP6022?

20:09

Из rail-to-rail был именно этот доступнее для меня.

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

timurko
12:38

О, это было бы очень круто! А то думаю заказывать с али, не знаю пока что. Пока сделал на доступных мне LM358 измерение тока. Но не нравится что с 0.06В ноль показывает. Как я понял это как раз связано с rail-to-rail характеристикой.

19:29

Опубликовал

Это норма, попробуйте делать измерения со средней точкой.

12val12
10:58
+2

@Выход ниже на более чем вольт по сравнению с напряжением питанием, то есть использовать этот ОУ в схемах с низким Uпит не советую, ведь тогда будут полезными (использоваться) не 12 разрядов АЦП, а в данном случае всего чуть более 7-бит!@

это не совсем   верно ..

просто вместо диапазона кодов 3-4095  от 0.003 до 3.3

будет доступно например  3-2854    от 0.003 до  2.3 вольт

… потеря до 40 % динамического диапазона  но это ж не 7 бит.

14:25

Здравствуйте. Мне статья во многом помогла разобраться но у меня не работали преобразования большее 1 цикла. Пока я не установил настройки вот так:

DMA continuous Requests Enable

Долго ломал голову почему у меня не работало. Повторяю проект на STM32F411CEU6 или же в простонароде black pill.

20:58

У меня тоже есть такая платка:

https://cxemka.com/43-plata-razrabotchika-minif4-n...

B  это действительно так, для f4xx отличаются настройки несколько, проверил у себя в другом проекте:

Юрий
00:11

Не сочтите за нахальство — можно получить принципиальную схему, разобраться с

макеткой не смог.

спасибо

21:56

Как-то так там было

Советую для настоящих проектов использовать микросхему-усилитель по типу INAxxx, тем более что сейчас доступны китайские аналоги
Загрузка...