Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Точное измерение переменного тока датчиком ACS712 на Arduino: метод истинного RMS (TRMS)

Необходимые компоненты

О проекте

Автор (SurtrTech) показывает, как правильно измерять переменный ток с ACS712. Датчик основан на эффекте Холла: выходное напряжение пропорционально току в проводнике, гальванически разделённом с измеряемой цепью. Главная сложность — вычисление истинного корня из среднего квадрата (True RMS) для несинусоидальных сигналов (например, при управлении диммером/триаком).

Почему простой метод «пик-пик» не работает

Для чистой синусоиды RMS = (Vpp / 2) × 0,707. Но если форма сигнала искажена (обрезанная синусоида от фазового регулятора), пик-пик даёт завышенные значения. Пример: мультиметр показывает 0,21 А, простой код — 0,36 А.

Решение: библиотека Filters (статистический подход)

Библиотека Filters.h реализует скользящее окно накопления выборок и вычисляет сигму (стандартное отклонение) сигнала, что эквивалентно TRMS для нулевого среднего. Настройка выполняется двумя коэффициентами:

Калибровка

  1. С током 0 А измеряйте inputStats.sigma(). Если не 0 — задайте intercept = -measured_sigma.
  2. Подайте известный ток (например, лампа 75 Вт при 230 В → ~0,326 А). Измерьте sigma. Вычислите slope = I_real / sigma.
  3. Пропишите оба коэффициента в скетче.

Примеры кода (основные версии)

1. Тест формы сигнала (Serial Plotter)

#define CURRENT_PIN A0
void setup() {
  Serial.begin(9600);
  pinMode(CURRENT_PIN, INPUT);
}
void loop() {
  float val = analogRead(CURRENT_PIN);
  Serial.println(val);
  delay(100); // подберите задержку для видного синуса
}

2. Метод пик-пик (только для синусоиды)

#define SAMPLES 300
#define ACS_PIN A0
float highPeak, lowPeak, ampsPP, ampsRMS;
void setup() { Serial.begin(9600); pinMode(ACS_PIN, INPUT); }
void loop() {
  readAmps();
  ampsRMS = ampsPP * 0.3536 * 0.06; // 0.06 — эмпирический калибровочный коэф.
  Serial.print(ampsRMS); Serial.print("\t"); Serial.println(ampsPP);
  delay(200);
}
void readAmps() {
  highPeak = 0; lowPeak = 1024;
  for (int i=0; i highPeak) highPeak = v;
    if (v < lowPeak) lowPeak = v;
  }
  ampsPP = highPeak - lowPeak;
}

3. TRMS через библиотеку Filters (Serial)


#include 
#define ACS_PIN A0
float testFreq = 50.0;
float window = 40.0 / testFreq; // 800 мс окно
float intercept = 0;
float slope = 0.0752; // ПОДСТАВЬТЕ СВОИ ПОСЛЕ КАЛИБРОВКИ
unsigned long period = 1000, prev = 0;

void setup() {
  Serial.begin(9600);
  pinMode(ACS_PIN, INPUT);
}
void loop() {
  RunningStatistics stats;
  stats.setWindowSecs(window);
  while (true) {
    float v = analogRead(ACS_PIN);
    stats.input(v);
    if (millis() - prev >= period) {
      prev = millis();
      float amps = intercept + slope * stats.sigma();
      Serial.print("\t Amps: "); Serial.println(amps);
    }
  }
}

4. TRMS + LCD I²C


#include 
#include 
#define ACS_PIN A0
#define I2C_ADDR 0x27
LiquidCrystal_I2C lcd(I2C_ADDR, 2, 1, 0, 4, 5, 6, 7); // En, Rw, Rs, D4-D7
// ... те же параметры окна, intercept, slope ...
void setup() {
  lcd.begin(16,2);
  lcd.setBacklightPin(3, POSITIVE);
  lcd.setBacklight(HIGH);
}
void loop() {
  RunningStatistics stats;
  stats.setWindowSecs(window);
  while (true) {
    stats.input(analogRead(ACS_PIN));
    if (millis() - prev >= period) {
      prev = millis();
      float amps = intercept + slope * stats.sigma();
      lcd.clear();
      lcd.setCursor(2,0);
      lcd.print(amps); lcd.print(" A");
    }
  }
}

5. TRMS + OLED 128×32 (Adafruit SSD1306)


#include 
#include 
#include 
#define ACS_PIN A0
#define SCREEN_W 128
#define SCREEN_H 32
Adafruit_SSD1306 display(SCREEN_W, SCREEN_H, &Wire, -1);
// ... те же параметры ...
void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay(); display.display();
}
void loop() {
  RunningStatistics stats;
  stats.setWindowSecs(window);
  while (true) {
    stats.input(analogRead(ACS_PIN));
    if (millis() - prev >= period) {
      prev = millis();
      float amps = intercept + slope * stats.sigma();
      display.clearDisplay();
      display.setTextSize(3);
      display.setTextColor(WHITE);
      display.setCursor(15,10);
      display.print(amps); display.println(" A");
      display.display();
    }
  }
}

Схемы подключения

Важные замечания

Производственный процесс

  1. Измерение качества воздуха с OpenSensors: руководство по Arduino и Python
  2. Датчик CO2 K30: мониторинг качества воздуха в реальном времени на Arduino
  3. Устройство для общения глухосліпых людей с помощью 1Sheeld и Arduino
  4. Умная копилка: управление монетоприёмником на Arduino Nano
  5. Управление светодиодом по Bluetooth с Arduino: простой DIY-гид
  6. Интеграция ёмкостного сканера отпечатков DFRobot с Arduino или ESP8266
  7. Интерактивный HMI-проект на Nextion с Arduino Mega и датчиками
  8. Роботизированная рука 6 степеней свободы на Arduino Mega с управлением через Nunchuk
  9. Оживление рыбы Billy Bass с любым аудиоисточником — пошаговое руководство
  10. Измерение солнечной радиации на Arduino UNO с Ethernet Shield