Компоненты · 16 мин чтения

Датчик тока ACS712: измерение постоянного и переменного тока с Arduino

Как пользоваться датчиком тока ACS712: чувствительность моделей 5A/20A/30A, нулевая точка 2,5 V, код для Arduino (DC и AC RMS), расчёт мощности, делитель для ESP32 и INA219.

Датчик тока ACS712 — маленький недорогой модуль, который с помощью эффекта Холла измеряет ток, протекающий через цепь, и превращает его в напряжение, понятное Arduino. Когда тока нет, на выходе около 2,5 V; при токе в одном направлении напряжение растёт, в другом — падает. Значит, одним аналоговым пином можно измерять и постоянный ток (DC), и переменный (AC). Его используют, чтобы узнать, сколько тока потребляет мотор, следить за разрядом аккумулятора, понять, работает ли устройство, или подсчитать, какую мощность потребляет домашний прибор. Вдобавок измеряемая токовая цепь электрически изолирована от стороны Arduino.

В этом руководстве ты пошагово узнаешь, что находится внутри ACS712, чем отличаются модели 5A, 20A и 30A и какую из них выбрать, как подключить модуль последовательно с цепью, увидишь первый скетч для Arduino, который измеряет постоянный ток, научишься успокаивать скачущие показания усреднением, считать RMS для переменного тока, а также мощность (W) и энергию (Wh). Затем разберёмся, как подключить датчик к ESP32 и Raspberry Pi Pico с питанием 3,3 V через делитель напряжения, почему с сетевым напряжением нужна особая осторожность и почему для малых токов лучше выбрать INA219.

Модуль датчика тока ACS712 (версия 20A)
Модуль ACS712: маркировка ELC-20A на микросхеме означает версию на 20 ампер. Зелёный винтовой клеммник включается последовательно в измеряемую цепь, а пины VCC, OUT и GND идут к Arduino.

Что такое датчик тока ACS712 и как он работает?

ACS712 — микросхема с 8 выводами производства Allegro. Измеряемый ток проходит внутри микросхемы по толстой медной дорожке от выводов 1 и 2 к выводам 3 и 4. Сопротивление этой дорожки всего 1,2 mΩ: даже при 10 A на ней падает лишь 12 mV и рассеивается 0,12 W, так что на измеряемую цепь она почти не влияет. Ток, проходя по этому проводнику, создаёт магнитное поле, пропорциональное току. Датчик Холла, расположенный прямо над медной дорожкой, улавливает это поле, а встроенный усилитель превращает его в напряжение. Основы подробнее описаны в руководстве по датчикам Холла.

Между медной дорожкой, по которой идёт ток, и стороной, от которой питается микросхема, нет электрического соединения; их связывает только магнитное поле. Поэтому измеряемая линия и Arduino изолированы друг от друга (гальваническая развязка). Выходное напряжение подчиняется формуле Vout = VCC / 2 + Чувствительность × I. Если ток течёт от IP+ к IP−, выход поднимается выше 2,5 V, если в обратную сторону — опускается ниже. Кроме того, ACS712 — ратиометрический датчик: и нулевая точка, и чувствительность меняются пропорционально напряжению питания. Если питание падает до 4,8 V, нулевая точка становится 2,4 V, а чувствительность модели 5A снижается со 185 примерно до 178 mV/A.

ПараметрЗначение
Напряжение питания4,5–5,5 V (типично 5 V)
Ток потребленияТипично 10 mA, максимум 13 mA
Выход при нулевом токеVCC × 0,5 (2,5 V при 5 V)
Сопротивление проводника1,2 mΩ
Полоса пропускания80 kHz (уменьшается конденсатором на пине FILTER)
Полная погрешность выхода±1,5% при 25 °C
Электрическая прочность изоляции2,4 kV RMS (60 с)
Нагрузка на выходеНе менее 4,7 kΩ, не более 10 nF
Кратковременная перегрузка по току100 A (одиночный импульс, 100 мс)
Рабочая температураОт −40 до 85 °C
Подключения модуляVCC, OUT, GND и 2-контактный винтовой клеммник

Модели 5A, 20A и 30A: чувствительность и разрешение

ACS712 выпускается в трёх версиях, которые снаружи выглядят совершенно одинаково. Чтобы понять, какая у тебя, прочитай маркировку на микросхеме: ELC-05B измеряет ±5 A, ELC-20A — ±20 A, а ELC-30A — ±30 A. Чувствительность показывает, на сколько милливольт меняется выход при изменении тока на 1 A. Чем больше диапазон, тем ниже чувствительность, поэтому у моделей 20A и 30A выход даже при максимальном токе остаётся в пределах 0,5–4,5 V. В таблице ниже также видно, скольким миллиамперам соответствует один шаг 10-битного АЦП Uno (4,88 mV) на каждой модели.

Модель (маркировка микросхемы)ДиапазонЧувствительностьВыход на краях диапазона1 шаг АЦП на UnoШум (фильтр 47 nF)
ACS712ELCTR-05B±5 A185 mV/A (180–190)1,58–3,43 V≈ 26 mA21 mV ≈ 0,11 A (размах)
ACS712ELCTR-20A±20 A100 mV/A (96–104)0,50–4,50 V≈ 49 mA11 mV ≈ 0,11 A (размах)
ACS712ELCTR-30A±30 A66 mV/A (63–69)0,52–4,48 V≈ 74 mA7 mV ≈ 0,11 A (размах)

Из таблицы следуют два важных вывода. Первый: шум в пересчёте на ток у всех трёх моделей примерно 0,1 A; если взять модель 30A для нагрузки 2 A, две трети разрешения пропадут впустую. Правило простое: выбирай самую маленькую модель, которая с запасом покрывает максимальный измеряемый ток (для переменного тока — пиковое значение). Например, для DC-мотора на 12 V, потребляющего не больше 2–3 A, подойдёт модель 5A, а для обогревателя на 1500 W — модель 20A. Второй: ACS712 не рассчитан на малые токи — светодиод, потребляющий несколько миллиампер, или ESP32 в глубоком сне им не измерить. Для этой задачи гораздо лучше подходит INA219, о которой речь пойдёт в конце руководства.

Подключение ACS712: Arduino Uno, ESP32 и Pico

У модуля ACS712 две стороны. Сторона с винтовым клеммником относится к измеряемой цепи: ток должен входить через одну клемму и выходить через другую, поэтому модуль включается последовательно с нагрузкой, как амперметр. Обычно разрезают плюсовой провод источника питания: конец, идущий от источника, подключают к одной стороне клеммника, а конец, идущий к нагрузке, — к другой. Сторона с тремя пинами подключается к Arduino. ACS712 работает только от 5 V; с ESP32 и Pico модуль тоже питают от пина, на котором есть 5 V, а его выход считывают через делитель напряжения.

Пин ACS712Arduino UnoESP32Raspberry Pi Pico
VCC5V5V (на некоторых платах VIN)VBUS (пин 40)
OUTA0GPIO 34 (через делитель 10k/20k)GP26 (через делитель 10k/20k)
GNDGNDGNDGND
Винтовой клеммникПоследовательно с нагрузкойПоследовательно с нагрузкойПоследовательно с нагрузкой
Никогда не подключай две клеммы прямо к плюсу и минусу источника питания, то есть параллельно, как вольтметр. Сопротивление внутреннего проводника всего 1,2 mΩ, так что это настоящее короткое замыкание: источник выдаёт максимальный ток, на какой способен, аккумулятор или адаптер повреждается, а провода и модуль могут сгореть. Измеряемый ток всегда должен проходить через нагрузку (мотор, лампу или резистор).

Кроме микросхемы, деталей на модуле совсем немного: развязывающий конденсатор в цепи питания, небольшой конденсатор на пине FILTER, задающий полосу пропускания, светодиод питания (D1) и его резистор (R1). Надпись 102 на R1 означает 1 kΩ; такие маркировки легко расшифровать с помощью утилиты SMD-кодов. Поскольку ACS712 изолирован, при одном только измерении тока минус измеряемой цепи не нужно соединять с GND Arduino.

Пошагово: измерение постоянного тока с Arduino

  1. Подключи пин VCC модуля к пину 5V Arduino, GND — к GND, а OUT — к A0. Светодиод питания на плате должен загореться.
  2. Разрежь плюсовой провод цепи, которую нужно измерить: конец от источника питания подключи к одной стороне клеммника, а конец, идущий к нагрузке (например, к мотору на 12 V или светодиодной ленте), — к другой.
  3. Держи источник питания нагрузки выключенным и загрузи скетч ниже. При запуске он измеряет нулевую точку, пока ток не течёт.
  4. Открой «Монитор порта» (Serial Monitor) на скорости 9600 бод: без тока значение должно держаться около 0,00 A и колебаться не больше чем на несколько сотых ампера.
  5. Включи источник питания нагрузки. Если ток показывается отрицательным, поменяй местами два провода в клеммнике или умножь результат на −1.
  6. Задай в коде SENSITIVITY под свою модель: 0.185 для 5A, 0.100 для 20A и 0.066 для 30A.
C++ (Arduino IDE)
1// ACS712 ile DC akım ölçme / DC current measurement with ACS712
2const int SENSOR_PIN = A0;            // ACS712 OUT pini / ACS712 OUT pin
3const float SENSITIVITY = 0.185;      // V/A: 5A=0.185, 20A=0.100, 30A=0.066
4const float ADC_STEP = 5.0 / 1024.0;  // bir ADC basamağı (V) / one ADC step (V)
5const int SAMPLES = 200;              // ortalama için örnek sayısı / samples to average
6
7float zeroRaw = 512.0;                // akım yokken ham değer / raw value at zero current
8
9// SAMPLES kez okuyup ortalamayı döndürür / reads SAMPLES times and returns the average
10float readAverageRaw() {
11  long sum = 0;
12  for (int i = 0; i < SAMPLES; i++) {
13    sum += analogRead(SENSOR_PIN);
14  }
15  return sum / (float)SAMPLES;
16}
17
18void setup() {
19  Serial.begin(9600);
20  delay(500);                         // sensörün oturmasını bekle / let the sensor settle
21  zeroRaw = readAverageRaw();         // yük KAPALIYKEN sıfır noktası / zero point with the load OFF
22  Serial.print(F("Sifir noktasi / Zero point: "));
23  Serial.print(zeroRaw * ADC_STEP, 3);
24  Serial.println(F(" V"));
25}
26
27void loop() {
28  float raw = readAverageRaw();
29  float current = (raw - zeroRaw) * ADC_STEP / SENSITIVITY;  // amper / amps
30
31  Serial.print(F("Akim / Current: "));
32  Serial.print(current, 2);
33  Serial.println(F(" A"));
34  delay(500);
35}

Для каждого измерения скетч усредняет 200 результатов analogRead; на Uno один analogRead занимает около 0,11 мс, так что это примерно 22 мс. Ток вычисляется по формуле I = (сырое − ноль) × (5 / 1024) / чувствительность. Например, у модели 5A при нулевой точке 512 среднее показание 550 даёт разницу в 38 шагов; это 38 × 4,88 mV = 185,5 mV, а значит, ток равен 185,5 / 185 ≈ 1,00 A. Измерять нулевую точку при запуске, а не принимать её за 2,5 V, важно: собственное смещение микросхемы и небольшие разности потенциалов на линии земли платы сдвигают её на несколько шагов, и эта ошибка добавляется к каждому измерению.

При чтении ACS712 на Arduino Uno не меняй опорное напряжение командой вроде analogReference(INTERNAL); оставь стандартное опорное напряжение 5 V. Поскольку ACS712 ратиометрический, даже если напряжение USB просядет до 4,8 V, и выход датчика, и опорное напряжение АЦП уменьшатся в одинаковой пропорции; сырые значения не изменятся, и 5.0 в коде само по себе останется верным. У ESP32 и Pico такого преимущества нет, потому что их опорное напряжение АЦП не зависит от питания, поэтому там мы применим небольшую поправку по нулевой точке.

Шум и усреднение

Выход ACS712 дрожит даже при постоянном токе. Первая причина — собственный шум датчика Холла: производитель приводит значения шума из таблицы выше для конденсатора 47 nF на пине FILTER, что соответствует полосе около 2 kHz. Однако на большинстве модулей там стоит 1 nF, как в типовой схеме производителя; полоса расширяется до 80 kHz, а шум становится в несколько раз выше. Вторая причина — АЦП: даже на модели 5A Uno измеряет шагами по 26 mA, и последний разряд всегда прыгает вверх-вниз. Случайный шум уменьшается пропорционально квадратному корню из числа усредняемых отсчётов: 16 отсчётов снижают его в четыре раза, 256 — в шестнадцать. Другие способы фильтрации описаны в руководстве по фильтрации данных датчиков.

  • Усреднение нескольких отсчётов: для постоянного тока усредняй 100–500 отсчётов. Если растянуть их на 20 мс, в среднем взаимно погасятся и помехи 50 Hz от сети.
  • Экспоненциальное скользящее среднее: подмешивай каждое новое показание к старому по формуле фильтр = фильтр + 0,1 × (новое − фильтр); памяти почти не нужно, а на дисплее получается спокойное значение.
  • Мёртвая зона: чтобы без подключённой нагрузки не видеть значения вроде 0,03 A, считай нулём результаты, модуль которых меньше 0,05 A.
  • Аппаратный фильтр: если умеешь паять, добавь конденсатор 47 nF параллельно тому, что стоит на пине FILTER, и полоса сузится примерно до 2 kHz; для постоянного тока и сетевого тока 50 Hz этого более чем достаточно.
  • Держи модуль подальше от магнитных полей: ACS712 — датчик Холла; магнит, динамик или другой провод с большим током поблизости сдвинут показания.
  • Обновляй нулевую точку: с температурой нулевая точка уплывает на несколько милливольт; в проектах, которые работают долго, измеряй ноль заново, пока нагрузка выключена.
Цифровой мультиметр со щупами
Для калибровки ACS712 включи мультиметр в режиме измерения тока последовательно в ту же линию и сравни два показания.

Усреднение убирает шум, но не исправляет систематическую ошибку. Чувствительность может отличаться от микросхемы к микросхеме на несколько процентов; у модели 5A она лежит в пределах от 180 до 190 mV/A. Для максимальной точности включи мультиметр в режиме измерения тока последовательно в ту же линию, что и ACS712, пропусти известный ток, например 1–2 A, и сравни два значения. Если мультиметр показывает 2,00 A, а Arduino — 1,94 A, поправочный коэффициент равен 2,00 / 1,94 = 1,031; раздели SENSITIVITY в коде на это число (0.185 / 1.031 ≈ 0.179), и показания совпадут с мультиметром.

Измерение переменного тока: расчёт RMS

Ток в сети постоянно меняет направление: частота составляет 50 Hz в Европе и большей части мира и 60 Hz в США. Поэтому выход ACS712 рисует синусоиду вокруг 2,5 V, среднее которой соответствует нулевому току; если запустить скетч для постоянного тока на нагрузке переменного, получатся бессмысленные значения около 0 A. Для переменного тока важна величина RMS (действующее значение): она равна постоянному току, который выделяет столько же тепла, и именно её используют мультиметры, предохранители и этикетки приборов. Расчёт следует названию: из каждого отсчёта вычитаешь нулевую точку, возводишь в квадрат (Square), усредняешь квадраты (Mean) и извлекаешь квадратный корень (Root).

Длина окна измерения важна: если в него не помещается целое число периодов, результат каждый раз немного меняется. Один период длится 20 мс при 50 Hz и 16,7 мс при 60 Hz. Окно 100 мс вмещает ровно 5 периодов при 50 Hz и ровно 6 при 60 Hz, поэтому правильно работает в обеих сетях, а Uno успевает сделать за это время около 900 отсчётов. Для чистой синусоиды пиковое значение в 1,414 раза больше RMS, так что можно просто разделить пик на √2. Но такие нагрузки, как зарядки для телефонов, светодиодные лампы или диммеры, потребляют импульсный несинусоидальный ток, и на них этот упрощённый способ ошибается; скетч ниже считает истинное RMS (true RMS), поэтому с такими нагрузками он гораздо точнее. Пиковое значение должно оставаться в пределах диапазона модели:

МодельПредел пикового токаМакс. переменный ток (RMS, синус)Примерная мощность при 230 V
5A±5 A3,5 A≈ 800 W
20A±20 A14,1 A≈ 3250 W
30A±30 A21,2 A≈ 4900 W
C++ (Arduino IDE)
1// ACS712 ile AC akım (RMS) ve görünür güç / AC current (RMS) and apparent power with ACS712
2const int SENSOR_PIN = A0;
3const float SENSITIVITY = 0.100;      // 20A modül: 100 mV/A / 20A module: 100 mV/A
4const float ADC_STEP = 5.0 / 1024.0;
5const unsigned long WINDOW_MS = 100;  // 50 Hz'te 5, 60 Hz'te 6 tam periyot / 5 cycles at 50 Hz, 6 at 60 Hz
6const float MAINS_VOLTAGE = 230.0;    // şebeke gerilimi (V) / mains voltage (V)
7
8float noiseRms = 0.0;                 // yük yokken ölçülen gürültü (A) / noise measured with no load (A)
9
10// Pencere boyunca örnek alır, ortalamayı çıkarıp RMS hesaplar / samples over the window, removes the mean, returns RMS
11float readRmsAmps() {
12  long sum = 0;
13  unsigned long sumSq = 0;
14  unsigned int n = 0;
15  unsigned long start = millis();
16  while (millis() - start < WINDOW_MS) {
17    int d = analogRead(SENSOR_PIN) - 512;  // 2,5 V'u sıfıra yaklaştır / shift 2.5 V to about zero
18    sum += d;
19    sumSq += (long)d * d;
20    n++;
21  }
22  float mean = sum / (float)n;                       // sıfır noktası kayması / zero point offset
23  float variance = sumSq / (float)n - mean * mean;   // yalnız AC kısım / AC part only
24  if (variance < 0) variance = 0;
25  return sqrt(variance) * ADC_STEP / SENSITIVITY;
26}
27
28void setup() {
29  Serial.begin(9600);
30  delay(500);
31  noiseRms = readRmsAmps();           // ilk ölçüm yük KAPALIYKEN / first reading with the load OFF
32  Serial.print(F("Gurultu / Noise: "));
33  Serial.print(noiseRms, 3);
34  Serial.println(F(" A"));
35}
36
37void loop() {
38  float irms = readRmsAmps();
39  float sq = irms * irms - noiseRms * noiseRms;  // gürültüyü karesel çıkar / subtract noise in quadrature
40  irms = (sq > 0) ? sqrt(sq) : 0.0;
41  float apparentPower = MAINS_VOLTAGE * irms;     // VA; dirençli yükte ≈ W / VA; ≈ W for resistive loads
42
43  Serial.print(F("Irms: "));
44  Serial.print(irms, 3);
45  Serial.print(F(" A   Guc / Power: "));
46  Serial.print(apparentPower, 1);
47  Serial.println(F(" VA"));
48  delay(1000);
49}

Этот скетч не хранит нулевую точку как фиксированное число: в каждом окне он находит среднее отсчётов и вычитает его. Математически это квадратный корень из дисперсии: RMS² = среднее квадратов − квадрат среднего. Поскольку среднее переменного тока за целое число периодов равно нулю, найденное среднее — это ровно ошибка нулевой точки, и она исправляется автоматически, даже если уплывает с температурой. Шум, измеренный при запуске с выключенной нагрузкой, вычитается квадратично, потому что шум и реальный ток независимы, а значения RMS складываются через квадраты. Без этого шага даже без подключённой нагрузки на экране появлялись бы «призрачные» значения вроде 0,1 A и 23 VA. Пример: утюг на 1000 W при 230 V потребляет около 4,35 A; его пик 6,1 A выходит за диапазон модели 5A, поэтому измеряй его моделью 20A.

Сетевое напряжение опасно для жизни. Изоляция внутри микросхемы ACS712 надёжная (электрическая прочность 2,4 kV RMS), но на дешёвых модулях винты клеммника и пайка на обратной стороне платы находятся под сетевым напряжением и ничем не закрыты. Подключай всё только при вынутой из розетки вилке, помести модуль в закрытый пластиковый корпус, поставь в линию предохранитель и ничего не трогай, пока цепь под напряжением. Измерять сеть, когда Arduino подключена к компьютеру по USB, опасно и для компьютера при любой неисправности; безопаснее выводить результаты на дисплей или передавать их по беспроводной связи через ESP32. Если опыта работы с сетевой проводкой нет, не проводи этот эксперимент в одиночку; школьникам и студентам — только вместе со взрослым, который разбирается в электрике.

Гораздо безопаснее измерять ток бытового прибора разъёмным трансформатором тока, например SCT-013: для него не нужно разрезать ни одного провода. Он защёлкивается вокруг кабеля, как токоизмерительные клещи, и вообще не имеет металлического контакта с сетью. Следить нужно лишь за тем, чтобы трансформатор охватывал только фазный или только нулевой провод: если охватить оба сразу, поля встречных токов взаимно компенсируются и результат будет нулевым. Трансформаторы тока измеряют только переменный ток; для постоянного нужен ACS712 или INA219.

Расчёт мощности (W) и энергии (Wh)

Когда ток известен, мощность находится одним умножением: P = V × I. Если аккумулятор на 12 V питает мотор, потребляющий 1,5 A, мощность равна 12 × 1,5 = 18 W; проверить это можно калькулятором закона Ома. Энергия — это мощность, умноженная на время: если мотор на 18 W работает 2 часа, он расходует 36 Wh. Скетч делает это так: при каждом измерении умножает мощность на прошедшее время и суммирует результат. Для измерения напряжения подойдёт модуль, который продаётся как датчик напряжения 0–25 V; внутри у него делитель напряжения из резисторов 30 kΩ и 7,5 kΩ, который делит входное напряжение на 5. Если хочешь рассчитать делитель со своими номиналами резисторов, воспользуйся утилитой делителя напряжения.

C++ (Arduino IDE)
1// ACS712 + gerilim sensörü ile güç (W) ve enerji (Wh) / power (W) and energy (Wh) with ACS712 + voltage sensor
2const int CURRENT_PIN = A0;           // ACS712 OUT
3const int VOLTAGE_PIN = A1;           // 0-25 V gerilim sensörü S pini / 0-25 V voltage sensor S pin
4const float SENSITIVITY = 0.185;      // 5A modül / 5A module (V/A)
5const float DIVIDER_RATIO = 5.0;      // (30k + 7,5k) / 7,5k = 5 / divider ratio
6const float ADC_STEP = 5.0 / 1024.0;
7const int SAMPLES = 200;
8
9float zeroRaw = 512.0;
10float energyWh = 0.0;                 // biriken enerji / accumulated energy
11unsigned long lastMs = 0;
12
13float averageRaw(int pin) {
14  long sum = 0;
15  for (int i = 0; i < SAMPLES; i++) sum += analogRead(pin);
16  return sum / (float)SAMPLES;
17}
18
19void setup() {
20  Serial.begin(9600);
21  delay(500);
22  zeroRaw = averageRaw(CURRENT_PIN);  // yük kapalıyken sıfır noktası / zero point with the load off
23  lastMs = millis();
24}
25
26void loop() {
27  float current = (averageRaw(CURRENT_PIN) - zeroRaw) * ADC_STEP / SENSITIVITY;
28  float voltage = averageRaw(VOLTAGE_PIN) * ADC_STEP * DIVIDER_RATIO;
29  float power = voltage * current;    // P = V x I (W)
30
31  unsigned long now = millis();
32  energyWh += power * (now - lastMs) / 3600000.0;  // W x saat = Wh / W x hours = Wh
33  lastMs = now;
34
35  Serial.print(voltage, 2);  Serial.print(F(" V   "));
36  Serial.print(current, 2);  Serial.print(F(" A   "));
37  Serial.print(power, 1);    Serial.print(F(" W   "));
38  Serial.print(energyWh, 3); Serial.println(F(" Wh"));
39  delay(1000);
40}

Поскольку модуль напряжения подключается между плюсом и минусом измеряемой цепи, на этот раз минус цепи и GND Arduino нужно соединить; почему, объясняется в руководстве по общей земле. Чтобы оценить, сколько часов продержится аккумулятор, объедини измеренный средний ток с расчётами mAh и Wh или с калькулятором времени работы от батареи. С переменным током всё немного иначе: произведение Vrms × Irms — это полная мощность, она измеряется в VA; активная мощность (W) равна ей, умноженной на коэффициент мощности. У резистивных нагрузок, таких как электрочайник, утюг и лампа накаливания, коэффициент мощности очень близок к 1, поэтому VA ≈ W. У моторов, адаптеров и светодиодных ламп он может быть от 0,5 до 0,9; чтобы измерить активную мощность, нужно одновременно оцифровывать и форму напряжения, для чего применяют изолированные модули датчика напряжения, например ZMPT101B.

ACS712 с ESP32: чтение через делитель напряжения

ESP32 работает от 3,3 V, а её аналоговые входы измеряют примерно до 3,1 V; подача на пин больше 3,6 V может повредить плату. ACS712 же работает только от 5 V, и его выход у моделей 20A и 30A может достигать 4,5 V, а при перегрузке по току — почти 5 V. Поэтому датчик питают от пина 5V платы ESP32 (на некоторых платах VIN), а OUT пропускают через делитель напряжения. Хороший выбор — 10 kΩ + 20 kΩ: от OUT через 10 kΩ к пину ESP32, а от этой же точки через 20 kΩ к GND. Коэффициент деления 20 / 30 = 0,667, а суммарные 30 kΩ с запасом выполняют требование ACS712 к нагрузке не менее 4,7 kΩ.

Выход ACS712ЗначениеНапряжение на пине ESP32
0,50 V−20 A на модели 20A0,33 V
2,50 VНулевой ток1,67 V
4,50 V+20 A на модели 20A3,00 V
5,00 VНасыщение при перегрузке по току3,33 V

В коде две тонкости. Во-первых, АЦП ESP32 нелинеен у краёв диапазона, поэтому вместо сырых значений мы используем функцию analogReadMilliVolts(), которая применяет калибровочные данные, записанные в микросхему на заводе. GPIO 34 находится на ADC1 и работает при включённом Wi-Fi; пины ADC2 вместе с Wi-Fi использовать нельзя. Во-вторых, ратиометрического удобства Uno здесь нет: опорное напряжение АЦП ESP32 фиксировано, а чувствительность ACS712 меняется вместе с 5 V от USB. Решение — простой приём: поскольку без тока выход равен половине VCC, умножь нулевую точку, измеренную при запуске, на 2 — получишь реальное напряжение питания датчика и по нему поправишь чувствительность. Так как одна и та же ошибка присутствует и в нулевой точке, и в измеряемом сигнале, этот способ заодно компенсирует допуск резисторов делителя. Скетч делает отсчёты в течение 100 мс и выдаёт сразу два результата: для нагрузки постоянного тока смотри на первое число, для сетевого прибора — на второе.

C++ (Arduino IDE)
1// ESP32 + ACS712 (10k/20k gerilim bölücüyle) / ESP32 + ACS712 (with a 10k/20k voltage divider)
2const int SENSOR_PIN = 34;            // ADC1_CH6, Wi-Fi açıkken de çalışır / works while Wi-Fi is on
3const float DIVIDER = 20.0 / 30.0;    // R2 / (R1 + R2) = 20k / 30k
4const float SENS_AT_5V = 185.0;       // mV/A: 5A=185, 20A=100, 30A=66
5const unsigned long WINDOW_MS = 100;  // 50 Hz'te 5 tam periyot / 5 full cycles at 50 Hz
6
7float zeroMv = 2500.0;                // akım yokken sensör çıkışı (mV) / sensor output at zero current (mV)
8float sensMv = SENS_AT_5V;            // düzeltilmiş hassasiyet (mV/A) / corrected sensitivity (mV/A)
9
10// Bölücüden önceki gerilimin ortalaması (mV) / average voltage before the divider (mV)
11float averageMv(int samples) {
12  uint32_t sum = 0;
13  for (int i = 0; i < samples; i++) sum += analogReadMilliVolts(SENSOR_PIN);
14  return sum / (float)samples / DIVIDER;
15}
16
17// Pencere boyunca okur: DC (ortalama) ve AC (RMS) akım / reads over the window: DC (mean) and AC (RMS) current
18void measure(float &dcAmps, float &acAmps) {
19  double sum = 0, sumSq = 0;
20  uint32_t n = 0;
21  uint32_t start = millis();
22  while (millis() - start < WINDOW_MS) {
23    double d = analogReadMilliVolts(SENSOR_PIN) / DIVIDER - zeroMv;
24    sum += d;
25    sumSq += d * d;
26    n++;
27  }
28  double mean = sum / n;
29  double variance = sumSq / n - mean * mean;
30  if (variance < 0) variance = 0;
31  dcAmps = mean / sensMv;
32  acAmps = sqrt(variance) / sensMv;
33}
34
35void setup() {
36  Serial.begin(115200);
37  analogReadResolution(12);
38  delay(500);
39  zeroMv = averageMv(1000);                    // yük KAPALIYKEN / with the load OFF
40  sensMv = SENS_AT_5V * (2.0 * zeroMv) / 5000.0;  // oransal düzeltme: VCC = 2 x sıfır / ratiometric fix: VCC = 2 x zero
41  Serial.printf("Sifir / Zero: %.0f mV  Hassasiyet / Sensitivity: %.1f mV/A\n", zeroMv, sensMv);
42}
43
44void loop() {
45  float dc, ac;
46  measure(dc, ac);
47  Serial.printf("DC: %.2f A   AC (RMS): %.2f A\n", dc, ac);
48  delay(1000);
49}

ACS712 с Raspberry Pi Pico и MicroPython

Raspberry Pi Pico тоже работает от 3,3 V, поэтому подключение такое же, как у ESP32: VCC датчика ACS712 подключи к VBUS (пин 40), на котором есть 5 V, пока Pico питается от USB, а OUT через тот же делитель 10k/20k — к GP26 (ADC0, пин 31). В MicroPython read_u16() возвращает значение от 0 до 65535, а напряжение = сырое × 3,3 / 65535. АЦП у Pico 12-битный; вместе с делителем на модели 5A он на бумаге измеряет шагами примерно по 6,5 mA, то есть примерно в четыре раза точнее, чем Uno. Код ниже измеряет нулевую точку при запуске, применяет ратиометрическую поправку, а затем каждую секунду выводит постоянный ток и действующее значение переменного (AC RMS).

MicroPython
1from machine import ADC
2import time
3import math
4
5adc = ADC(26)            # GP26 = ADC0, fiziksel pin 31 / physical pin 31
6VREF = 3.3               # ADC referansı (V) / ADC reference (V)
7DIVIDER = 20 / 30        # 10k/20k bölücü oranı / 10k/20k divider ratio
8SENS_AT_5V = 0.185       # V/A: 5A=0.185, 20A=0.100, 30A=0.066
9
10
11def read_volts(samples=200):
12    # bölücüden önceki ortalama gerilim / average voltage before the divider
13    total = 0
14    for _ in range(samples):
15        total += adc.read_u16()          # 0-65535
16    return total / samples * VREF / 65535 / DIVIDER
17
18
19zero = read_volts(1000)                  # yük KAPALIYKEN / with the load OFF
20sens = SENS_AT_5V * (2 * zero) / 5.0     # oransal düzeltme / ratiometric correction
21print("Sifir / Zero: {:.3f} V".format(zero))
22
23
24def read_rms(window_ms=100):
25    # 100 ms = 50 Hz'te 5 periyot / 5 cycles at 50 Hz
26    n = 0
27    s = 0.0
28    s2 = 0.0
29    start = time.ticks_ms()
30    while time.ticks_diff(time.ticks_ms(), start) < window_ms:
31        v = adc.read_u16() * VREF / 65535 / DIVIDER - zero
32        s += v
33        s2 += v * v
34        n += 1
35    mean = s / n
36    return math.sqrt(max(s2 / n - mean * mean, 0)) / sens
37
38
39while True:
40    dc = (read_volts() - zero) / sens
41    print("DC: {:.2f} A   AC (RMS): {:.2f} A".format(dc, read_rms()))
42    time.sleep(1)

ACS712 или INA219?

INA219 — микросхема Texas Instruments для контроля тока и напряжения, которая общается по I2C. Вместо эффекта Холла она измеряет падение напряжения на маленьком шунтирующем резисторе (на модулях обычно 0,1 Ω), через который течёт ток. Популярные модули измеряют до ±3,2 A с разрешением около 0,8 mA, сами считывают напряжение шины до 26 V и вычисляют мощность внутри микросхемы. Так что по одному подключению I2C ты получаешь сразу напряжение, ток и мощность, без возни с АЦП, усреднением и калибровкой нуля. Зато она не даёт изоляции между измеряемой цепью и Arduino, не измеряет переменный ток и не работает выше 26 V.

ХарактеристикаACS712Модуль INA219
Метод измеренияЭффект Холла (магнитный)Шунтирующий резистор (0,1 Ω)
Диапазон тока±5 / ±20 / ±30 A±3,2 A (зависит от шунта)
Разрешение26–74 mA с Uno≈ 0,8 mA
Переменный токДаНет
Напряжение и мощностьНет (нужен отдельный делитель)Да (до 26 V)
ИзоляцияДаНет
ИнтерфейсАналоговый выходI2C (адрес 0x40–0x4F)
ПитаниеТолько 5 V3–5,5 V
Лучше всего дляМоторы, обогреватели, сетевые приборы, большой токАккумуляторы, солнечные панели, потребление датчиков и плат
C++ (Arduino IDE)
1#include <Wire.h>
2#include <Adafruit_INA219.h>
3
4Adafruit_INA219 ina219;               // varsayılan adres 0x40 / default address 0x40
5
6void setup() {
7  Serial.begin(9600);
8  if (!ina219.begin()) {
9    Serial.println(F("INA219 bulunamadi / INA219 not found"));
10    while (true) delay(10);
11  }
12  // ina219.setCalibration_16V_400mA();  // küçük akımda daha ince çözünürlük / finer resolution for small currents
13}
14
15void loop() {
16  float busV = ina219.getBusVoltage_V();        // yük tarafındaki gerilim / voltage on the load side
17  float current_mA = ina219.getCurrent_mA();    // akım (mA) / current (mA)
18  float power_mW = ina219.getPower_mW();        // güç (mW) / power (mW)
19
20  Serial.print(busV, 2);       Serial.print(F(" V   "));
21  Serial.print(current_mA, 1); Serial.print(F(" mA   "));
22  Serial.print(power_mW, 0);   Serial.println(F(" mW"));
23  delay(1000);
24}

Для кода установи библиотеку Adafruit INA219 через «Менеджер библиотек» (Library Manager). Пины SDA и SCL модуля подключи к A4 и A5 на Uno; измеряемый ток должен входить в VIN+ и выходить из VIN− к нагрузке, а GND INA219 должен быть общим с измеряемой цепью. Коротко: если нужно измерять постоянный ток от нескольких миллиампер до 3 A вместе с напряжением, выбирай INA219; если нужны большие токи, переменный ток или изоляция, правильный выбор — ACS712.

Идеи проектов с ACS712

  • Защита мотора от перегрузки по току: когда DC-мотор, управляемый через L298N, заклинивает, его ток резко растёт; при превышении заданного порога останови мотор и подай звуковой сигнал.
  • Монитор аккумулятора и солнечной панели: измеряй ток заряда и разряда с учётом направления, умножай на напряжение, накапливай Wh и выводи результаты на OLED-дисплей.
  • Умная розетка: включай и выключай розетку модулем реле, с помощью ACS712 проверяй, действительно ли прибор работает, и отправляй данные в Home Assistant по MQTT.
  • Уведомление об окончании стирки: когда ток несколько минут держится ниже заданного значения, пусть ESP32 отправит сообщение в Telegram.
  • Сигнализация сухого хода насоса: когда вода заканчивается, ток, потребляемый насосом, падает; распознай это и выключи насос.
  • Регистратор энергии: раз в минуту записывай ток и мощность на SD-карту или в Google Таблицы и строй график суточного потребления.
  • Настольный измеритель мощности: добавь ACS712 в проект вольтметра на Arduino, и получится прибор, который показывает напряжение, ток и мощность на одном экране.

Частые ошибки и решения

СимптомВероятная причинаРешение
Без тока показывает 0,1–0,3 AВ коде нулевая точка принята за 2,5 V или 512Измеряй нулевую точку при запуске с выключенной нагрузкой и добавь небольшую мёртвую зону
Значение постоянно скачетЧтение по одному отсчёту, широкая полоса фильтра 1 nFУсредняй 100–500 отсчётов; при необходимости добавь 47 nF на FILTER
Ток получается отрицательнымТок проходит через клеммник в обратном направленииПоменяй провода местами или умножь результат на −1
Значения около 0 A на нагрузке переменного токаИспользован код для постоянного тока; среднее синусоиды равно нулюИспользуй скетч с расчётом RMS
Значения всегда на несколько процентов выше или нижеНеверное значение для модели или разброс чувствительностиВыбери 0.185, 0.100 или 0.066 по маркировке микросхемы и откалибруй мультиметром
Сырое значение застряло на 0 или 1023OUT на неправильном пине или замкнут на VCC, ток вне диапазона моделиПроверь подключение и при необходимости возьми модель побольше
Источник питания отключается, провод греетсяКлеммник подключён параллельно источнику (короткое замыкание)Подключи модуль последовательно с нагрузкой
Нестабильные значения на ESP32Нет делителя, пин ADC2 или сырой analogReadИспользуй делитель 10k/20k, GPIO 34 и analogReadMilliVolts
Показания меняются рядом с магнитомДатчик Холла улавливает внешнее магнитное полеДержи модуль подальше от магнитов, динамиков и проводов с большим током
Проще всего проверить, правильно ли работает датчик тока, с помощью известной нагрузки. Например, резистор 10 Ω на 12 V по закону Ома потребляет 1,2 A и превращает в тепло 14,4 W, поэтому выбирай мощный резистор, рассчитанный минимум на 20–25 W. Если измеренное значение близко к 1,2 A, подключение и код в порядке.

ACS712 — отличный способ начать изучать измерение тока: одним аналоговым пином измеряешь постоянный и переменный ток, а несколькими строками кода получаешь ещё и мощность с энергией. Если выбрать подходящую модель, измерить нулевую точку, усреднять отсчёты и откалибровать датчик мультиметром, результаты будут надёжными с точностью до нескольких процентов. Основы аналогового чтения можно закрепить в нашем руководстве по АЦП. В приложении BlueGrays есть проекты вроде чтения аналогового датчика, цифрового вольтметра с LCD-дисплеем, включения лампы 220V через реле и регистратора данных на ESP32 — с пошаговыми схемами подключения и кодом.

Частые вопросы

Какой ток измеряет ACS712 и какую модель выбрать?

ACS712 выпускается в трёх моделях: на ±5 A, ±20 A и ±30 A, с чувствительностью 185, 100 и 66 mV/A соответственно. Выбирай самую маленькую модель, которая покрывает максимальный измеряемый ток (для переменного тока — пиковое значение): при том же токе маленькая модель даёт больший размах выходного сигнала и лучшее разрешение. Модель можно определить по маркировке ELC-05B, ELC-20A или ELC-30A на микросхеме.

Почему ACS712 выдаёт 2,5 V без тока?

Выход начинается с половины напряжения питания, чтобы ACS712 мог измерять ток в обоих направлениях. При токе в одну сторону выход поднимается выше 2,5 V, в другую — опускается ниже. Если питание не ровно 5 V, нулевая точка сдвигается к VCC / 2, поэтому лучше всего измерять её при запуске.

Может ли ACS712 измерять сетевой ток?

Да: электрическая прочность изоляции микросхемы — 2,4 kV RMS; при 230 V модель 5A подходит для нагрузок примерно до 800 W, а модель 20A — примерно до 3250 W. Однако винтовой клеммник и пайка модуля находятся под сетевым напряжением, поэтому подключай его только при вынутой вилке, помещай в закрытый корпус и не работай в одиночку, если опыта нет. Безопаснее накладной трансформатор тока, например SCT-013, для которого не нужно разрезать провода.

Работает ли ACS712 с ESP32 или от 3,3 V?

ACS712 нужно 4,5–5,5 V, а от 3,3 V он не даёт правильных результатов. С ESP32 и Raspberry Pi Pico питай модуль от пина 5V, VIN или VBUS, а выход подключай к аналоговому пину через делитель напряжения 10 kΩ + 20 kΩ. Тогда даже выход, близкий к 5 V, на пине останется ниже 3,33 V.

Почему ACS712 не показывает ноль без тока?

Причины две: в коде нулевая точка принята ровно за 2,5 V или 512, а у датчика есть собственный шум. Измеряй нулевую точку при запуске с выключенной нагрузкой, усредняй 100–500 отсчётов и добавь небольшую мёртвую зону, например 0,05 A. Для переменного тока квадратичное вычитание шума убирает «призрачный» ток в режиме простоя.

ACS712 или INA219: что лучше?

Зависит от задачи. INA219 работает по I2C и выдаёт сразу ток, напряжение и мощность с разрешением около 0,8 mA до ±3,2 A, поэтому для аккумуляторов и небольших цепей постоянного тока она гораздо точнее. ACS712 измеряет до 30 A, считывает и переменный ток и изолирует измеряемую цепь от Arduino.

Все проекты
Измерение освещённости с LDR
#11Новичок

Измерение освещённости с LDR

Хочешь увидеть яркость своей комнаты в виде числа? LDR — маленькая деталь, реагирующая на свет, — измеряет освещённость вокруг, а Arduino каждые полсекунды выводит значение на экран компьютера. Закрой

4.6(81)
139
Измерение освещённости модулем LDR на ESP32
#113Новичок

Измерение освещённости модулем LDR на ESP32

Наблюдение в мониторе порта в реальном времени за сырым значением ADC модуля LDR и относительным процентом освещённости, вычисленным по опорным значениям темноты и света. Этот процент — не измерение в люксах. Учит логике калибровки модуля. Идеально выполнить его перед проектом 10, потому что он нужен для определения порога.

4.6(36)
55
Цифровой вольтметр с LCD-дисплеем
#56Средний
Premium

Цифровой вольтметр с LCD-дисплеем

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

4.5(27)
36
Включение лампы 220V кнопкой (удержание)
#19Продвинутый
Premium

Включение лампы 220V кнопкой (удержание)

Пока ты держишь кнопку, горит настоящая лампа на 220 вольт, а как только отпустишь — гаснет. Слабый сигнал Arduino не может зажечь лампу напрямую, поэтому между ними стоит реле — выключатель с электри

4.4(30)
38
Регулировка яркости светодиода потенциометром на ESP32 (аналог → PWM)
#115Средний
Premium

Регулировка яркости светодиода потенциометром на ESP32 (аналог → PWM)

В этом проекте яркость светодиода плавно регулируется потенциометром. Пин АЦП ESP32 читает напряжение 0–3,3V с потенциометра, затем это значение превращается в сигнал PWM (широтно-импульсная модуляция) и подаётся на светодиод. В результате при повороте потенциометра светодиод постепенно становится ярче или тусклее. В Arduino Core 3.0+ можно сразу использовать analogWrite(); на ESP32-S2/S3 разрешение АЦП фиксировано — 12 бит.

4.5(19)
32
LCD-экран с I2C
#32Новичок
Premium

LCD-экран с I2C

Дай своему Arduino собственный экран и заставь его написать первое сообщение. Двухстрочный LCD-экран подключается всего несколькими проводами; в верхней строке появляется приветствие, затем второе соо

4.8(53)
70
I2C LCD-дисплей (16x2) на ESP32
#119Средний
Premium

I2C LCD-дисплей (16x2) на ESP32

В этом проекте символьный LCD-экран 16x2 подключается к ESP32 по протоколу I2C и выводит текст. Благодаря I2C экраном можно управлять всего двумя пинами данных (SDA и SCL), не тратя 6+ пинов, как при классическом параллельном подключении. Код печатает постоянное сообщение в первой строке и счётчик, растущий каждую секунду, во второй. Кроме того, при запуске работает сканер I2C, который выводит адрес дисплея в монитор порта.

4.9(23)
40
Регистратор температуры на ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
#144Продвинутый
Premium

Регистратор температуры на ESP32 (DHT22 + DS1307 RTC + microSD + OLED)

Собери на ESP32 регистратор температуры с отметками времени! Каждую минуту читай температуру и влажность с DHT22, бери реальное время из DS1307 RTC и записывай всё на карту microSD в формате CSV. OLED показывает текущую температуру (крупным шрифтом), влажность в процентах, время и счётчик записей. Файл /temp_log.csv на SD-карте открывается в Excel, Google Sheets или Python pandas — идеально для теплиц, комнат, лабораторий и хранения продуктов.

4.7(7)
12