锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

ESP32+ACS712霍尔电流传感器小结

时间:2023-10-16 12:37:02 t交流电流传感器4

ESP32用ADC1即36引脚analogRead读数为111111 1111 最大值为4095的1111, 资料 传送门
上述读取的最大电压.3V,实测3V当读数为4095时,模拟电压为3V,万用表测量误差可能存在,当满量程为3时.3V吧。
demo如下:

void setup() { 
          Serial.begin(115200); }   void loop() { 
          int vtmp=analogRead(36); //ADC获取电压     Serial.printf("采样值为%:d\n", vtmp);   Serial.printf("电压为:%.3fV\n", vtmp * 3.3 / 4095);   delay(1000); } 

ACS712霍尔互感器,5A量程输出为185mV/A,20A量程输出为100mV/A,30A量程输出为66mV/A,我买的是20A的。
接线如下

ESP32 ACS712
5V VCC
G GND
36 OUT

在空载的情况下,ACS理论上,712输出是2.5V,2.5V即0点。如果测量是直流电,数量为2.5 ;如果测量交流电,值为2.5 2.5-上。实测后发现几个问题:

  1. 空载输出不是2.5V但在2.7±0.2V浮动。
    解决方案:用50次测量取平均值,使值相对稳定。有资料说要在硬件上加低通滤波,不会搞T_T。
  2. 就算是零点2.5V稳定,按20A量程输出为100mV/A如果电流测量为20A,那ACS712输出电压为2.5 0.120=4.5V,而ESP32的测量模拟量为3.3V,已经超过了ESP32的量程。怎么办?
    解决方案:想想工作电压是否为5V,零点为2.5V,工作电压为3.3V,零点也到1吗?.65V是的?按照这个想法来测量,确实如此。就是不知道还是1000。mV/A,待测量。如果仍然是这个标准,满量程输出电压为1.65 0.1
    20=3.75V,粗心也可以测量。假设工作电压下降,输出标准同比下降,那么20A标准变为66mV/A,满测量输出为:4.5*0.66=2.97V,那就在ESP测量范围在32范围内,但只是猜测,待测量确认。

注:github搜索ACS712会出来很多别人写的。arduino都是针对的arduino模拟测量程5V ,10位采样是1023写的。需要调整程序中的参数。例如,我将根据以下内容进行调整ESP32参数有所改进:
ACS712.h

#ifndef ACS712_h #define ACS712_h  #include   #define ADC_SCALE 4095.0//采样值 arduino为1023 #define VREF 3.3 //参考电压,即全量程模拟电压,arduino为5 #define DEFAULT_FREQUENCY 50///交流频率   enum ACS712_type { 
       ACS712_05B, ACS712_20A, ACS712_30A};   class ACS712 { 
        public:
    ACS712(ACS712_type type, uint8_t _pin);
    int calibrate(); // 零点校准值
    void setZeroPoint(int _zero);
    void setSensitivity(float sens);
    float getCurrentDC(); // 测直流电
    float getCurrentAC(uint16_t frequency = 50); // 测交流电


private:
    int zero = 2048;//零点模拟值
    float sensitivity;
    uint8_t pin;
};

#endif

ACS712.cpp

#include "ACS712.h"

ACS712::ACS712(ACS712_type type, uint8_t _pin) { 
       
    pin = _pin;
    // 不同量程模块的灵敏度,工作电压变了,这里的灵敏度值估计也要同比调整
    switch (type) { 
       
        case ACS712_05B: // 5A
            sensitivity = 0.185;
            break;
        case ACS712_20A: // 20A
            sensitivity = 0.100;
            break;
        case ACS712_30A: // 30A
            sensitivity = 0.066;
            break;
    }
}

// 零点校准
int ACS712::calibrate() { 
       
    uint16_t acc = 0;
    for (int i = 0; i < 50; i++) { 
       // 50次取样平均,原版10次
        acc += analogRead(pin);
    }
    zero = acc / 50;
    return zero;
}

// 设置零点值
void ACS712::setZeroPoint(int _zero) { 
       
    zero = _zero;
}

// 设置灵敏度值
void ACS712::setSensitivity(float sens) { 
       
    sensitivity = sens;
}

// 测量直流电,单位:mA 毫安
float ACS712::getCurrentDC() { 
       
    int16_t acc = 0;
    for (int i = 0; i < 50; i++) { 
       //50次采样,原版10次
        acc += analogRead(pin) - zero;
    }
    float I = (float)acc / 50.0 / ADC_SCALE * VREF / sensitivity * 1000 ;
    return I;
}

// 测量交流电,单位:mA 毫安
float ACS712::getCurrentAC(uint16_t frequency) { 
       
    uint32_t period = 1000000 / frequency;
    uint32_t t_start = micros();


    uint32_t Isum = 0, measurements_count = 0;
    int32_t Inow;


    while (micros() - t_start < period) { 
       
        Inow = analogRead(pin) - zero;
        Isum += Inow*Inow;
        measurements_count++;
    }


    float Irms = sqrt(Isum / measurements_count) / ADC_SCALE * VREF / sensitivity * 1000;
    return Irms;
}

测量直流电DEMO

#include "ACS712.h"

/* This example shows how to measure DC current */

// We have 30 amps version sensor connected to A0 pin of arduino
// Replace with your version if necessary
ACS712 sensor(ACS712_30A, A0);

void setup() { 
       
  Serial.begin(115200);


  // calibrate() method calibrates zero point of sensor,
  // It is not necessary, but may positively affect the accuracy
  // Ensure that no current flows through the sensor at this moment
  // If you are not sure that the current through the sensor will not leak during calibration - comment out this method
  Serial.println("Calibrating... Ensure that no current flows through the sensor at this moment");
  int zero = sensor.calibrate();
  Serial.println("Done!");
  Serial.println("Zero point for this sensor = " + zero);
}

void loop() { 
       
  // Read current from sensor
  float I = sensor.getCurrentDC();
  
  // Send it to serial
  Serial.println(String("I = ") + I + " mA");
  
  // Wait a second before the new measurement
  delay(1000);
}

测量交流电DEMO

#include "ACS712.h"


/* This example shows how to measure the power consumption of devices in 230V electrical system or any other system with alternative current */


// We have 30 amps version sensor connected to A0 pin of arduino
// Replace with your version if necessary
ACS712 sensor(ACS712_30A, A0);


void setup() { 
       
  Serial.begin(9600);

  // calibrate() method calibrates zero point of sensor,
  // It is not necessary, but may positively affect the accuracy
  // Ensure that no current flows through the sensor at this moment
  // If you are not sure that the current through the sensor will not leak during calibration - comment out this method
  Serial.println("Calibrating... Ensure that no current flows through the sensor at this moment");
  sensor.calibrate();
  Serial.println("Done!");
}

void loop() { 
       
  // We use 230V because it is the common standard in European countries
  // Change to your local, if necessary
  float U = 230;


  // To measure current we need to know the frequency of current
  // By default 50Hz is used, but you can specify desired frequency
  // as first argument to getCurrentAC() method, if necessary
  float I = sensor.getCurrentAC();

  // To calculate the power we need voltage multiplied by current
  float P = U * I;

  Serial.println(String("I = ") + I + " mA");
  Serial.println(String("P = ") + P + " Watts");


  delay(1000);
}

原版库传送门

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章