Due to high demand, expect some shipping delays at this time - orders may not ship for up to 2-3 business days.
0

ADS1115 HSTS016L Hall Effect Current
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

ADS1115 HSTS016L Hall Effect Current

by jimk123 on Mon Dec 13, 2021 6:53 pm

I have been trying on and off for a few years to measure DC current on a sub panel on my boat (12v) system. I have a commercial product that uses a shunt on the main battery but when plugged into shore power it always measures positive current since a charger is always on but I want to see how much current a DC panel is using (the sub panel can be up to 50 amps) I bought this handheld meter https://www.bluesea.com/products/8110/M ... er_-_AC_DC that seems to be very accurate when I clamp it on the positive wire to the sub panel. I am hoping to do something similar with an arduino with the ultimate goal of using a feather ESP32 and adafruit dataio service to record DC current every minute.

I bought this sensor after seeing it used in a commercial marine power monitor, YHDC has a model called HSTS016L has models able to measure current values ranges from 10A up to 200A I have the 10amp model. The output voltage of this sensor is 2.5V +/- 0.625V

https://pdf1.alldatasheet.com/datasheet ... L-10A.html

The sensor has 4 output pins: RED (5V input), BLACK (0V Gnd), YELLOW (Analog Output), and WHITE (Analog for Calibration).

and used this doc to test it on a UNO board https://solarduino.com/how-to-measure-d ... ansformer/ which seemed to work pretty good. Then I saw this sensor from adafruit ADS1115 with more accuracy and a I2C interface which I think will be a better fit with a ESP32.

Right now I am using an UNO with the ADS1115 and the following code but I am getting odd readings from A0 and A1 on the ADS1115, attached is the code and a pic of the wiring. I am in way over my head on this one :( any help would be greatly appreciated. The output values never change, regardless if I have a load on the sensor (I am testing with 2 different LED bulbs, one draws around .12 amp, the other around 1 amp.

this is the serial output:
setup
Getting single-ended readings from AIN0..3
ADC Range: +/- 6.144V (1 bit = 3mV)
Scanning I2C devices...
I2C device found at address 0x48
I2C devices found: 1
AIN0: 2047
AIN1: 2047



Code: Select all | TOGGLE FULL SIZE
// https://www.adafruit.com/product/1085  ADS1115 16-Bit ADC - 4 Channel with Programmable Gain Amplifier Product ID: 1085
// 0x48 (1001000) ADR -> GND

// How to measure DC and AC current using HSTS016L Hall Effect Current Transformer 10amp model
 
// The sensor has 4 output pins:
//  RED (5V input),
//  BLACK (0V Gnd),
//  YELLOW (Analog Output), pin A1
//  WHITE (Analog for Calibration) pin A2
 
#include <Wire.h>
#include <Adafruit_ADS1X15.h>   // ver 2.3.0 installed on 12/11/21

Adafruit_ADS1015 ads1015;
int decimalPrecision = 2;                   // decimal places for all values shown in LED Display & Serial Monitor

/* 1- AC Current Measurement */

//int currentAnalogInputPin = A1;             // Which pin to measure Current Value (A0 is reserved for LCD Display Shield Button function)
//int calibrationPin = A2;                    // Which pin to calibrate offset middle value
float manualOffset = 0.0; //0.00;                  // Key in value to manually offset the initial value

// If using "Hall-Effect" Current Transformer, key in value using this formula: mVperAmp = maximum voltage range (in milli volt) / current rating of CT
// For example, a 10A Hall-Effect Current Transformer rated at 10A, 2.5V +/- 0.625V, mVperAmp will be 625 mV / 10A = 62.5mV/A
// For example, a 20A Hall-Effect Current Transformer rated at 20A, 2.5V +/- 0.625V, mVperAmp will be 625 mV / 20A = 31.25mV/A
// For example, a 50A Hall-Effect Current Transformer rated at 50A, 2.5V +/- 0.625V, mVperAmp will be 625 mV / 50A = 12.5 mV/A
                                                   
float mVperAmpValue = 62.5;        // 10amp sensor         
float supplyVoltage = 5000;                 // Analog input pin maximum supply voltage, Arduino Uno or Mega is 5000mV while Arduino Nano or Node MCU is 3300mV
float offsetSampleRead = 0;                 /* to read the value of a sample for offset purpose later */
float currentSampleRead  = 0;               /* to read the value of a sample including currentOffset1 value*/
float currentLastSample  = 0;               /* to count time for each sample. Technically 1 milli second 1 sample is taken */
float currentSampleSum   = 0;               /* accumulation of sample readings */
float currentSampleCount = 0;               /* to count number of sample. */
float currentMean ;                         /* to calculate the average value from all samples, in analog values*/
float RMSCurrentMean ;                      /* square roof of currentMean, in analog values */   
float FinalRMSCurrent ;                     /* the final RMS current reading*/


   
void setup(void)
{
  Serial.begin(115200);
  Serial.println("setup");
 
  Serial.println("Getting single-ended readings from AIN0..3");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV)");
  ads1015.begin();
//  ads1015.setGain(GAIN_ONE);     // 1x gain   +/- 4.096V  1 bit = 2mV
  ads1015.setGain(GAIN_TWO);     // 2x gain   +/- 2.048V  1 bit = 1mV
// ads1015.setGain(GAIN_FOUR);    // 4x gain   +/- 1.024V  1 bit = 0.5mV
// ads1015.setGain(GAIN_EIGHT);   // 8x gain   +/- 0.512V  1 bit = 0.25mV
// ads1015.setGain(GAIN_SIXTEEN); // 16x gain  +/- 0.256V  1 bit = 0.125mV
scanI2C();
}


void loop(void)
{
  int16_t adc0, adc1, adc2, adc3;

  adc0 = ads1015.readADC_SingleEnded(0);
  adc1 = ads1015.readADC_SingleEnded(1);
  //adc2 = ads1015.readADC_SingleEnded(2);
 // adc3 = ads1015.readADC_SingleEnded(3);
  Serial.print("AIN0: "); Serial.println(adc0);
  Serial.print("AIN1: "); Serial.println(adc1);
 // Serial.print("AIN2: "); Serial.println(adc2);
 // Serial.print("AIN3: "); Serial.println(adc3);
 // Serial.println(" ");


 

          delay(250);
}


void scanI2C()
{
  byte error, address;
  int nDevices;
   
 
  Serial.println("Scanning I2C devices...");


 nDevices = 0;
 for (address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print(F("I2C device found at address 0x"));
      Serial.println(address, HEX);
      nDevices++;
     
      delay(250);
    }   
    else if (error == 4)
    {
      Serial.print("Unknown error at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  Serial.print("I2C devices found: ");Serial.println(nDevices);
}




IMG-3298.jpg
IMG-3298.jpg (770.29 KiB) Viewed 442 times

jimk123
 
Posts: 374
Joined: Sun Dec 26, 2010 7:04 pm

Re: ADS1115 HSTS016L Hall Effect Current

by adafruit_support_mike on Thu Jan 06, 2022 8:40 pm

Drop back to the example sketches from the ADS1115 library, and start by measuring the voltage of a potentiometer. If you see the measured voltage change as you turn the pot's wiper, swap the connections over to your current sensor. Do you see the readings change in response to changes in current?

adafruit_support_mike
 
Posts: 64547
Joined: Thu Feb 11, 2010 2:51 pm

Re: ADS1115 HSTS016L Hall Effect Current

by jimk123 on Sun Jan 23, 2022 11:48 am

Hi Mike
I purchased these items from your store as suggested:

https://www.adafruit.com/product/1085 ADS1115 16-Bit ADC - 4 Channel with Programmable Gain Amplifier
https://www.adafruit.com/product/562 Panel Mount 10K potentiometer (Breadboard Friendly) - 10K Linear

As much as possible I followed this tutorial for the wiring using a UNO board
https://learn.adafruit.com/adafruit-4-c ... s?view=all

wiring:
ADS1115 0x48 (1001000) ADR -> GND

UNO
NEG <--> one side pot
A5 SCL blue <--> ADS1115 SCL
A4 SDA yellow <--> ADS1115 SDA
5v <--> one side pot

try Single Ended Connection
middle terminal pot <--> ADS1115 A0

I used a Fluke multimeter connected to the positive side of the pot and the neg side to the middle terminal on the post.
DC voltage readings observed on the multimeter and the value in the Arduino monitor window as I twisted the knob:

0.0v AIN0: 1719
1.0v AIN0: 1383
1.5v AIN0: 1218
2.0v AIN0: 1045
2.5v AIN0: 886
3.0v AIN0: 711
3.5v AIN0: 552
4.0v AIN0: 387
4.5v AIN0: 219
5.0v AIN0: 52
5.16v AIN0: 0 (this was with the pot at its max which was powered by the 5v pin on the uno)

How do I convert those numbers into something meaningful ? also is it possible to get a wider range (accuracy) over the 0-5v, it is my understanding the ADS1115 can sense from 0-4095 ?

Part 2 of this project is to use a clamp current sensor (see attached pdf) but as suggested trying to understand how the ADS1115 board works, ultimately I want to use the ADS1115 with your Huzzah32 ESP32 feather board.

thanks
Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include <Adafruit_ADS1X15.h>

Adafruit_ADS1015 ads1015;

void setup(void)
{
  Serial.begin(115200);
  Serial.println("Hello!");
 
 
  ads1015.begin();
  ads1015.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV (default)
// ads1015.setGain(GAIN_ONE);     // 1x gain   +/- 4.096V  1 bit = 2mV
// ads1015.setGain(GAIN_TWO);     // 2x gain   +/- 2.048V  1 bit = 1mV
// ads1015.setGain(GAIN_FOUR);    // 4x gain   +/- 1.024V  1 bit = 0.5mV
// ads1015.setGain(GAIN_EIGHT);   // 8x gain   +/- 0.512V  1 bit = 0.25mV
// ads1015.setGain(GAIN_SIXTEEN); // 16x gain  +/- 0.256V  1 bit = 0.125mV
}

void loop(void)
{
  int16_t adc0, adc1, adc2, adc3;

  adc0 = ads1015.readADC_SingleEnded(0);
  //adc1 = ads1015.readADC_SingleEnded(1);
  //adc2 = ads1015.readADC_SingleEnded(2);
  //adc3 = ads1015.readADC_SingleEnded(3);
  Serial.print("AIN0: "); Serial.println(adc0);
  //Serial.print("AIN1: "); Serial.println(adc1);
  //Serial.print("AIN2: "); Serial.println(adc2);
  //Serial.print("AIN3: "); Serial.println(adc3);
  //Serial.println(" ");
 
  delay(1000);
}


IMG-3391.jpg
IMG-3391.jpg (784.85 KiB) Viewed 271 times

HSTS016L-10A-2.5±0.625V (1).pdf
(879.27 KiB) Downloaded 11 times

jimk123
 
Posts: 374
Joined: Sun Dec 26, 2010 7:04 pm

Re: ADS1115 HSTS016L Hall Effect Current

by adafruit_support_mike on Wed Jan 26, 2022 5:58 pm

jimk123 wrote:I used a Fluke multimeter connected to the positive side of the pot and the neg side to the middle terminal on the post.

That would account for the decreasing values you saw. With the probes in that position, you'll be measuring the difference between the wiper voltage and the supply voltage.

In general, voltage is measured with the negative probe connected to GND. That's the reference voltage for everything else in the circuit.

jimk123 wrote:How do I convert those numbers into something meaningful ?

For the settings in the code, multiply the number of bits by 3mV:

Code: Select all | TOGGLE FULL SIZE
0.0v AIN0: 1719     ( 5.157V )
1.0v AIN0: 1383     ( 4.149V )
1.5v AIN0: 1218     ( 3.654V )
2.0v AIN0: 1045     ( 3.135V )
2.5v AIN0: 886      ( 2.658V )
3.0v AIN0: 711      ( 2.133V )
3.5v AIN0: 552      ( 1.656V )
4.0v AIN0: 387      ( 1.161V )
4.5v AIN0: 219      ( 1.161V )
5.0v AIN0: 52       ( 0.156V )
5.16v AIN0: 0       ( 0V     )
In all cases, the voltage calculated from the ADC reading and the voltage you measured with the multimeter add up to about 5.16V

jimk123 wrote:also is it possible to get a wider range (accuracy) over the 0-5v

First, as a point of vocabulary, range and accuracy are two different things:

- Range is the largest difference a device can measure.
- The smallest difference a device can measure is called 'resolution'.
- Accuracy is how well a sensor's output matches the value of a known standard.
- Precision is the amount of variation from one reading to the next when taking several measurements of the same standard.
- The output from a sensor is called a 'code'.
- A 'reading' is the sensor's output code converted to units of the property of interest.

Multiplying the ADC output codes (binary integers) by 3mV converted them into the voltage readings listed above. The fact that a one-digit difference between codes represents 3mV of difference in the input voltage defines the resolution.

The 'code -vs- reading' thing makes more sense when you see that the ADS1115 can be set to measure different ranges (at different resolutions):

Code: Select all | TOGGLE FULL SIZE
  ads1015.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV (default)
// ads1015.setGain(GAIN_ONE);     // 1x gain   +/- 4.096V  1 bit = 2mV
// ads1015.setGain(GAIN_TWO);     // 2x gain   +/- 2.048V  1 bit = 1mV
// ads1015.setGain(GAIN_FOUR);    // 4x gain   +/- 1.024V  1 bit = 0.5mV
// ads1015.setGain(GAIN_EIGHT);   // 8x gain   +/- 0.512V  1 bit = 0.25mV
// ads1015.setGain(GAIN_SIXTEEN); // 16x gain  +/- 0.256V  1 bit = 0.125mV
Regardless of the range/resolution, the output codes will always be binary integers.

jimk123 wrote:it is my understanding the ADS1115 can sense from 0-4095 ?

Not exactly. The ADS1115 has 4096 output codes, but they're signed integer values from -2048 to +2047.

You can only get the negative half of the range with a differential measurement (the relative voltage between two input pins). For a differential reading between AIN0 and AIN1 at 2/3 gain:

- AIN0=5V and AIN1=0V would give you output code 1666 (times 3mV = 5V)
- AIN0=0V and AIN1=5V would give you output code -1666 (times 3mV = -5V)

Single-ended readings only give you the 11 bits of resolution that represent the positive half of the range.

If you wanted to measure 0V to 5V at higher resolution, you could use GAIN=1 and take a differentlal reading with pin AIN1 tied to a constant 2.5V. That would give you output codes from -1250 to 1250 at a resolution of 2mV per bit. You'd only be using about half of the available range though (codes -2048 to 2047).

You could improve the resolution again by running the 5V through a 1k-4k voltage divider so the voltage to measure varies from 0V to 4.0V. Then you could use the GAIN=2 setting and take a differential reading with AIN1 tied to a constant 2V. That would give you output codes between -2000 and +2000 at a resolution of 1mV per bit. That would make almost all of the available codes map to readings within the range you want, at a resolution of 1mV per bit.

adafruit_support_mike
 
Posts: 64547
Joined: Thu Feb 11, 2010 2:51 pm

Please be positive and constructive with your questions and comments.