ADS1115 and measuring low current AC (using a ACS70331)

So I picked up an ACS70331 based sensor from seeed. Using the internal ADC of the ESP8266 board (10 bits) and some code provided by the ACS board manufacturer with some tweaks I am able to read a current that is showing up on my multimeter as 76mA, as 79mA with the ESP. Given other sensors I've tried, this one is doing great.

Here is the code that works:

#define RefVal 3.3
#define Pin A0

const int averageValue = 500;
long int sensorValue = 0;
float sensitivity = 1000.0 / 200.0; //1000mA per 200mV
float Vref = 1604.88;
void setup()
{
  Serial.begin(115200);
}
static float tempval;
void loop()
{
  for (int i = 0; i < 20; i++)
  {
    for (int i = 0; i < averageValue; i++)
    {
      int temp;
      temp = analogRead(A0);
      if (temp > sensorValue)
      {
        sensorValue = temp;
      }
      delayMicroseconds(40);
    }
    tempval += sensorValue;
  }
  sensorValue = tempval / 20.0;
  tempval = 0;
  // The on-board ADC is 10-bits
  // Different power supply will lead to different reference sources
  // example: 2^10 = 1024 -> 5V / 1024 ~= 4.88mV
  //          unitValue= 5.0 / 1024.0*1000 ;
  float unitValue = RefVal / 1024.0 * 1000 ;
  float voltage = unitValue * sensorValue;

  //When no load,Vref=initialValue
  Serial.print("initialValue: ");
  Serial.print(voltage);
  Serial.println("mV");

  float current = ((voltage - Vref) * sensitivity) * 0.707;
  voltage = unitValue * sensorValue - Vref;
  Serial.print(voltage);
  Serial.println("mV");

  Serial.print("current: ");
  Serial.print(current);
  Serial.println("mA");
  Serial.print("\n");
  sensorValue = 0;
  delay(1000);
}

Now, I figured that a 16bit ADC would give me less of a margin of error. I have the ADS1115 and came across this thread: AC Energy Meter calculation using ACS712 - General Electronics - Arduino Forum

I tried to "merge" methods found in the thread and in the first link (this first code block) with no luck; probably because I don't fully understand how to.

For example:
-the ADS has numerous "gain" methods that I am not sure if and which I should use and how that would affect the calculations. For example, say I read a single analog measurement from the sensor at the peak of the AC sinus wave. How would I get the current mathematically with this ADC?
-Numerous commenters in the linked thread mentioned changing the
sampling rate of the ADC and in other forum posts I've read people trying to do this with no luck. I've read other threads where some stated that the max sampling rate is too slow for AC and >1000 is preferred.
-the ADS has an internal reference yet many examples, including the one in the linked thread, have static values set for the voltage (e.g. 5, 3.3). Presumably, introduces errors if the supply voltage isn't perfect? What's the point of the internal reference then?

Code attempt:

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads(0x48);

int mVperAmp = 200;
double Voltage = 0;
double VRMS = 0;
double AmpsRMS = 0;

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

void loop() {
  Voltage = getVPP();
  VRMS = (Voltage / 2.0) * 0.707;
  AmpsRMS = (VRMS * 1000) / mVperAmp;
  Serial.print(AmpsRMS);
  Serial.println(" Amps RMS");
}

float getVPP()
{
  float result;
  int readValue;             //value read from the sensor
  int maxValue = 0;          // store max value here
  int minValue = 32768;          // store min value here
  uint32_t start_time = millis();
  while ((millis() - start_time) < 1000) //sample for 1 Sec
  {
    readValue = ads.readADC_SingleEnded(0);
    // see if you have a new maxValue
    if (readValue > maxValue)
    {
      /*record the maximum sensor value*/
      maxValue = readValue;
    }
    if (readValue < minValue)
    {
      /*record the maximum sensor value*/
      minValue = readValue;
    }
  }
  // Subtract min from max
  result = ((maxValue - minValue) * 3.3) / 32768;
  return result;
}

Reporting 30mA when multi-meter has it at 80mA.

Sorry for all the questions. I think I bit off more than I can chew.

More info: Voltage on ESP, ADS and ACS: 3.3v. ADS connected over i2c; ADDR pin to ground (default address). ACS in series with load and multimeter. Trying to measure less than 100mA AC.

A note: I am aware that the ACS does NOT have a high isolation voltage rating. I am simply trying to get a reliable reading with a current sensor, and the ADS, where the load is of low amperage (<100mA) until my other sensor arrives that has a greater isolation voltage. That being said, this sensor should be fine for testing as long as there isn't a surge.

I have another thread on detecting AC voltage with an opto. That is still alive, I am just waiting for parts and experimenting with other sensors.

Before you get carried away this is another magnetic sensor, and like Hall sensors will pick up stray magnetic fields, greatly limiting the accuracy available for low currents.

If you want to measure small currents accurately nothing beats a shunt resistor - you can't have isolation this way, but it will work with small currents.

MarkT:
Before you get carried away this is another magnetic sensor, and like Hall sensors will pick up stray magnetic fields, greatly limiting the accuracy available for low currents.

If you want to measure small currents accurately nothing beats a shunt resistor - you can't have isolation this way, but it will work with small currents.

Hey Mark, I understand that but, it works good enough with the on-board ADC, so I'm just trying to get it to work with the external one.

Update: I am going to trying to get this ADC working with this sensor using DC current first and update when I've got more to show/explain.

alex_fagard:
I have the ADS1115 and came across this thread...

Can't compare a ratiometic ADS712 with this non-ratiometric sensor.
They both need a different type of A/D for stable performance.
An ADS712 shouldn't be used with an absolute/voltage ADS1115 (or ESP8266), but this sensor can.
You seem to have the bi-directional version, with a zero-current point of 1.5volt and a ±1volt deviation for full current.
So sensor output can be 0.5 to 2.5volt.
Only a PGA gain of 1 of the ADS1115 would cover that range, but a 5volt (<4.5) supply would be needed for the ADS1115.
Leo..

Wawa:
Can't compare a ratiometic ADS712 with this non-ratiometric sensor.
They both need a different type of A/D for stable performance.
An ADS712 shouldn't be used with an absolute/voltage ADS1115 (or ESP8266), but this sensor can.
You seem to have the bi-directional version, with a zero-current point of 1.5volt and a ±1volt deviation for full current.
So sensor output can be 0.5 to 2.5volt.
Only a PGA gain of 1 of the ADS1115 would cover that range, but a 5volt (<4.5) supply would be needed for the ADS1115.
Leo..

I see what you are saying, but at the same time, are you sure that the supply voltage needs to be changed? I thought the gain was software not hardware based with this ADC? For one, the ACS current sensor is only a 3.3v device. I'm pretty sure I can connect the output of the ACS to the ADS when the ADS is running 5v, but I'll probably need something like this for the signal lines SDA/SCL of the ADC as the ESP is 3.3v. For example, if what you said is correct, wouldn't one need a supply voltage greater than the tolerance (5.5V max) of the ADC if one wanted to use the highest gain (6.144V)?

With regards to your comment on ratiometric sensors, do you have a suggestion regarding an i2c ADC that would work with ratiometric sensors? I see a lot of people using the ADS1115 and the ACS712, so I am curious as to why that is a bad choice and that others in this forum haven't steered them away from it.

alex_fagard:
are you sure that the supply voltage needs to be changed?

No, you're right. You can measure 2.5volt with a PGA gain of 1 and an ADS supply of 3.3volt.
But not with a PGA gain of 2 (>2.048volt will clip).
You will get a 14-bit span with these settings (you're using half of the span of a 15-bit (single-ended) A/D)
Note that the ADS is slower, so you won't be getting as many data points from your AC wave.

For ratiometric sensors you need an A/D chip without internal reference, or one where the internal reference is available to power the sensor.
Not many of them around.
Leo..

Wawa:
For ratiometric sensors you need an A/D chip without internal reference, or one where the internal reference is available to power the sensor.
Not many of them around.
Leo..

Is that because ratiometric sensors are proportional to the supply voltage, and if you have different references (adc internal vref and external supply) then your result will likely be skewed? Assuming both the internal reference and external reference is perfectly equal this wouldn't be an issue? Just trying to get a grasp on things :wink:

Yes.
If the supply of a ratiometric sensor goes up, output voltage goes up proportionally.
If supply (Vref) of a ratiometric A/D goes up, value goes down with the same proportion, resulting in cancelation of supply fluctuations.
If you mix up sensor and A/D types, then there is no cancelation anymore, and the setup becomes supply unstable.
Leo..

Wawa:
Yes.
If the supply of a ratiometric sensor goes up, output voltage goes up proportionally.
If supply (Vref) of a ratiometric A/D goes up, value goes down with the same proportion, resulting in cancelation of supply fluctuations.
If you mix up sensor and A/D types, then there is no cancelation anymore, and the setup becomes supply unstable.
Leo..

Ok, but say both are off of the same supply, the internal "vref" of the adc is unaffected because it tries to keep a stable output no matter the fluctuation? Otherwise, it wouldn't really be an issue so long as both are off of the same supply (same fluctuations).

This looks pretty cool. It meets the aforementioned requirements.

  1. fast adc
  2. no internal adc reference
  3. reference provided by external reference that powers both the adc and the current sensor

Unfortunate the current sensor they chose doesn't have a greater sensitivity. Do you think it would work to detect 100mA currents?

100mA is only 0.5% of a 20Amp.
It would make more sense to use the 5Amp version of that sensor.

I thought you only wanted to 'detect' that ~70mA solenoid current, not 'measure' it.
How did that opto current sensor work.
Leo..

Wawa:
100mA is only 0.5% of a 20Amp.
It would make more sense to use the 5Amp version of that sensor.

I thought you only wanted to 'detect' that ~70mA solenoid current, not 'measure' it.
How did that opto current sensor work.
Leo..

I agree, unfortunately, they've only got it in that one version :frowning: and it's also SPI and I can't spare the digital i/o.

As for the opto, got the parts today and it works fine using your diode method! Just a few tweaks regarding maybe a Schmidt trigger or different output cap to help smooth out the results. As for the current part, I'm just experimenting :wink: Ideally, since I'm having this circuit made, I'd like it to be multi-purpose for other applications so if I can squeeze an accurate current sensor in there I'd be happy.

As said, easier to bridge zero-crossing and gaps in software.
Something like

if (!sensorPin) nowMillis = millis();
millis() - nowMillis < 100 ? valveState = true : valveState = false;

Leo..