Измерение тока 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-бит!

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

Видос

1303
RSS
Нет комментариев. Ваш будет первым!
Загрузка...