Author Topic: Using a ASC712 current sensor with UNO  (Read 4499 times)

0 Members and 1 Guest are viewing this topic.

OperaHouse

  • Hero Member
  • *****
  • Posts: 1308
  • Country: us
Using a ASC712 current sensor with UNO
« on: September 23, 2016, 03:22:08 PM »
I've had a couple of these around for a while.  Actually just found them.  I buy the +-5A versions and use them with a shunt if more current is needed. I have heard they were noisy and not that accurate.  Found one of the four actually didn't work.  Wrote this simple program to test them.  They output 2.5V, half the power supply, as zero and are defined for a +- 1V swing from that.  From 1.5V to 3.5V doesn't use a lot of the A/D converts possible range.  Found it is best to read them with no current first and get that number of counts.  This will vary +- 20 counts from the nominal 511 counts.   Each count is .0244A so you multiply that number times the counts. I use the whole number 244 to keep the math integer. In testing I actually got better numbers using 249 with my sensor. This has to be divided by 10,000 later using float. It was a little disappointing. You expect to get more from a 50 cent chip these days.  I always put loop counters in my programs.  They are a basic building block to any program and allow relays etc to turn on and off in an orderly fashion.  The numbers on this really bounce around but these are useful for go/no go applications to see if a device is operating and current is normal.  long has to be used for ACScount and amps because at 5A these numbers when multiplied will exceed 32K.  This number is then divided by 10,000 to get amps to two decimal places.

// ACS712-1
// This program reads a ACS712 HALL sensor on pin A3
// Subtracts half the possible count value to get +_5A
// serial outputs data every second & flashes LED

 int second      = 0;
 int count        = 0;
 int ACScount   = 0;             // raw A/D of hall sensor
 int offset      = 520;           // amps offset
 int amps        = 0;             // A 1000X
 
void setup() 
{
   Serial.begin(9600);               //  setup serial
   pinMode(13, OUTPUT);          // sets the digital LED pin 13 as output
}

 
void loop()  {   
   
    long ACScount = analogRead (3);     // read sensor on pin A3
   
    if (count > 10)                                // 10 counts = 1 second
    {                                                   // this bracket indicates start of actions
                                                         // when IF is true
       count  = 0;                                 // reset count
       second =  second + 1;                 // ten counts = 1 second                         
    }                                                   // end of those operations
   
    delay(100);                                    // waits for a 1/10 second
                                                       
    long amps = (ACScount - offset) * 244;     // subtract about 1/2 counter range (1023) to
                                                         // get  center "zero" value for no current.  +-5A is
                                                        // aprox 205 counts each way from that center zero.
                                                        // each count = .0244A but we use whole numbers, 244
                                                        // in printout divide by 10,000.  long integer is used
                                                        // because number can exceed 32K
   
    //                       SEND DATA TO SERIAL IN TOOLS
    //           Printing takes time.  Comment out this in final working program.
    //           data every second
    if (count == 0)
{
    Serial.print(ACScount);                 // raw A/D count
    Serial.print(" A/D     ");         
    Serial.print(offset);                       // offset
    Serial.print(" offset     current = ");         
    Serial.print((float) amps/10000);    // amps
    Serial.print("A     ");
    Serial.print("      ");
    Serial.println(second);                   // second

    if (second > 32000) (second = 32000);       // limit upper second count
    count = count + 1;                        // increment count
}   
« Last Edit: September 24, 2016, 08:36:58 AM by OperaHouse »

OperaHouse

  • Hero Member
  • *****
  • Posts: 1308
  • Country: us
Re: Using a ASC712 current sensor with UNO
« Reply #1 on: September 23, 2016, 03:34:45 PM »
This next program is a little more sophisticated and uses my favorite function MAP.  The current sensor is connected to a power supply, 2A in this case.  You the program to read the raw sensor data and record the most typical value for + and _ flow.  These are plugged into the MAP routine.  MAP seems to work well with currents well over 2A, that will not be the limit of the reading as this will calculate values beyond 5A.  The more current you can test with the better.  My camp supply was only 3A.  The raw data is multiplied 8 times and gives a running average.  Just watch each reading as it comes up to value.  It takes a while but the result is a smoother number to work with.  The amp value 200 represents 2A so it stays an integer value. Using MAP also automatically takes care of the zero offset.  These are handy isolated sensors but are in no way precision.


// ACS712-2
// This program reads a ACS712 HALL sensor on pin A3
// Multiplies the value by 8 to get an average
// Calculates the amperage using MAP & adds offset

 int second     = 0;
 int count      = 0;
 int ACScount   = 0;             // raw A/D of hall sensor
 int amps       = 0;             // A 100X
 int ACSavg     = 0;             // averaged 8X value
void setup() 
{
   Serial.begin(9600);           //  setup serial
   pinMode(13, OUTPUT);          // sets the digital LED pin 13 as output
}

void loop()  {   
   
    ACScount = analogRead (3);                          // read sensor
   
    if (count > 10)                                     // 10 counts = 1 second
    {                                                   // this bracket indicates start of actions
                                                        // when IF is true
       count  = 0;                                      // reset count
       second =  second + 1;                            // ten counts = 1 second                         
    }                                                   // end of those operations
   
    delay(100);                                         // waits for a 1/10 second
   
                                                        // the following multiplies by 8
    ACSavg = ACSavg - ACSavg / 8;                       // subtract average reading
    ACSavg = ACSavg + ACScount;                         // add new reading
   
    amps = map (ACSavg, 3585, 4832, -200, 200);         // calculate amps @ +-2A measured
                                                        // higher the current the better
                                                        // this will calculate beyond 2A
                                                        // 1 count = .01A
                                                         
     
   
    //                       SEND DATA TO SERIAL IN TOOLS
    //           Printing takes time.  Comment out this in final working program.
    //           data every second
    if (count == 0)
{
    Serial.print(ACScount);                     // raw A/D count
    Serial.print(" A/D     ");         
    Serial.print(ACSavg);                       // averaged 8X
    Serial.print(" 8X avg     current = ");         
    Serial.print((float) amps/100);          // amps to two decimal places
    Serial.print("A    ");
    Serial.println(second);                     // second

    if (second > 32000) (second = 32000);       // limit upper second count
    count = count + 1;                          // increment count
}   
 
« Last Edit: September 23, 2016, 07:54:06 PM by OperaHouse »

Bruce S

  • Administrator
  • Super Hero Member Plus
  • *****
  • Posts: 5370
  • Country: us
  • USA
Re: Using a ASC712 current sensor with UNO
« Reply #2 on: September 23, 2016, 05:24:20 PM »
OperaHouse;
I'm finding that MAP is going to be very very useful to me when I start getting into the nitty gritty of the pumps and lights.
I know it's easy to merely take what the labeled power is and extrapolate the energy needed for the set times.
BUT being a curious person,,, I'm learning ahead so even I know what might be needed if I decide to take vacation(holiday) from work.
My novice idea is to take either the mean or the median of the numbers.

We shall see, getting all the parts in place, getting the code working all WITHOUT killing my winter crop is "complicated".

IF I find these cool little sensors, it would be well worth the price for rough numbers as they would level out with usable numbers.

BTW!! It's getting easier and easier to follow your coding  ;D.
Pure perseverance of trying codes on the "validate" and finding my typing mistakes is beginning to pay off.

I'm now using the cute little portable program on a 1Gb CF. I save the work to it and run it during lunch or play time.
A kind word often goes unsaid BUT never goes unheard

OperaHouse

  • Hero Member
  • *****
  • Posts: 1308
  • Country: us
Re: Using a ASC712 current sensor with UNO
« Reply #3 on: September 24, 2016, 10:33:02 AM »
Here is what these sensors look like for only $2.  You won't attach any big cables to these terminals.

http://www.ebay.com/itm/5A-Range-Current-Sensor-Module-ACS712-Electronic-Parts-ZH/122101638970?_trksid=p5713.c100284.m3505&_trkparms=aid%3D111001%26algo%3DREC.SEED%26ao%3D8%26asc%3D20140905073823%26meid%3D9b416b9a19df4c9cb2225a45eea24b4e%26pid%3D100284%26rk%3D2%26rkt%3D7%26sd%3D122101638970

I still do reckless coding and let the compiler figure it out.  I often skip putting a colon at the end or a parenthesis and misspell/typo a variable. My mind goes faster than my typing.  These sample programs are a convenient start to anyone's own requirement.    I would be interested in anyone's take on the code explanations I have provided as to what needs further explanation.

I have a refrigerator that runs off a HF inverter.  These inverters will lock out in an over/under voltage. situation.  They only reset when power switch is turned off.  Monitoring fridge current would allow you to reset the power in case of a problem.  Otherwise you need timers to limit run time in the program.

The following can be used on AC and should approximate the RMS current if you sample fast enough or long enough.  It turns every read into a positive number.  These are added every loop.  The number of loops is used as the multiplier for the current.  Sensor noise is eliminated by changing the value at which data is accepted into the count.  Second isn't a second in this example.

// ACS712-3
// This program reads a ACS712 HALL sensor on pin A3
// measuring AC current and adding to a count value
// serial outputs data every second & flashes LED

 int second     = 0;
 int count      = 0;
 int ACScount   = 0;             // raw A/D of hall sensor
 int offset         = 530;         // offset nominal for zero
 unsigned int amptotal   = 0;    // accumulated current
 int loopend    = 25;            // number of loops
 
void setup() 
{
   Serial.begin(9600);           //  setup serial
   pinMode(13, OUTPUT);       // sets the digital LED pin 13 as output
}

 
void loop()  {   
   
    ACScount = analogRead (3);                // read sensor on pin A3
    if (count > loopend)                            // end count
    {                                                       // this bracket indicates start of actions
                                                             // when IF is true
       count  = 0;                                      // reset count
       second =  second + 1;                      // increment second
       amptotal = 0;                                  // reset amp count       
    }                                                       // end of those operations
   
    delay(1);                                           // waits for a 1/1000 second or use program delay
   
    if (ACScount > offset + 10)amptotal = amptotal + (ACScount - offset);
 // add any positive number
    if (ACScount < offset - 10)amptotal = amptotal - (ACScount - offset);
 // subtract any negative number....which is an ADD
                                                        // every A/D read is added as a positive number
                                                        // by adding or subtracting to the nominal offset
                                                        // noise around zero is eliminated
                                                        // printout divide by 1000
                                                        // 25 loops is just a multiplier to make numbers come out
                                                       
   
    //                       SEND DATA TO SERIAL IN TOOLS
    //           Printing takes time.  Comment out this in final working program.
    //           data every second
    if (count == loopend)
{
    Serial.print(ACScount);                  // raw A/D count
    Serial.print(" A/D     ");         
    Serial.print(offset);                       // offset
    Serial.print(" offset     current = ");         
    Serial.print((float) amptotal / 1000);   // amps
    Serial.print("A     ");
    Serial.print("      ");
    Serial.println(second);                    // second

    if (second > 32000) (second = 32000);       // limit upper second count
    count = count + 1;                          // increment count
}   
 

This could also be done with the absolute function.......
 
    ACScount = ACScount - offset          // get any positive or negative number
    ACScount = abs(ACScount)             // get absolute value
                                                        // math functions can not be done inside abs function
     
if (ACScount > 10) amptotal = amptotal + ACScount; 
                                   // add any number greater than 10
                                   // every A/D read is added as a positive number
                                   // by suntracting the nominal offset and taking absolute value
                                   // noise around zero is eliminated by ignoring values under 10
     
« Last Edit: September 24, 2016, 12:05:33 PM by OperaHouse »

margusten

  • Jr. Member
  • **
  • Posts: 82
Re: Using a ASC712 current sensor with UNO
« Reply #4 on: September 26, 2016, 01:45:20 AM »
"I buy the +-5A versions and use them with a shunt if more current is needed."

This is interesting. How this home made shunt is made?
Can You give some pictures.

I was using 20A and 30A versions.

OperaHouse

  • Hero Member
  • *****
  • Posts: 1308
  • Country: us
Re: Using a ASC712 current sensor with UNO
« Reply #5 on: September 27, 2016, 12:47:02 PM »
I have not used these yet with an actual shunt so I do not know the dynamics.  I have used shunts with other current devices.  My refrigerator has a 50mv 100A current shunt.  A Turnegy $10 type of power monitor is bridged across that.  I know the fridge is 120A at startup and if I multiply the measurement on that by 8.6 I get the correct value.  These power meters say they are good for 100A, but the main complaint on the hobby boards is the solder melts on wires to the internal shunt resistor.  And that is powering a toy car!  Shunts are designed to handle current and not heat up much.  A change in temperature will change the resistance.

Any wire can be used as a shunt.  The lead from a controller down to a battery could be used as a shunt.  Every connection, crimp, wire and solder joint has some resistance and these can change over time.  Shunts have separate terminals for the monitoring equipment because the main connections can introduce uncertainty.  Any two resistors in parallel will share a proportionate value of current.  This can be calculated, but you will never have the values to put in the equation.  So take a 3-4 inch piece of #12 copper wire, solder on two wires near each end and run those to the ACS712.  Look for a multiple of the actual current.  Start with some long wires to the ACS712.  Shorten the wires if the multiple is too low.  Only in an alternate universe can you put 30A through one of those circuit board, connector and chip.

margusten

  • Jr. Member
  • **
  • Posts: 82
Re: Using a ASC712 current sensor with UNO
« Reply #6 on: September 30, 2016, 01:49:37 AM »
Yes, I was wondering how this small ACS712 circuit board can handle 30A current.
Probably only a few seconds.

OperaHouse

  • Hero Member
  • *****
  • Posts: 1308
  • Country: us
Re: Using a ASC712 current sensor with UNO
« Reply #7 on: September 30, 2016, 12:02:14 PM »
That is the same problem with current ratings of a  FET.  The leads of a FET are many times smaller than the metal strip in a fuse.  They rate these at very small pulses.  Just took a FET out of a TV.  It was rated at 50A.  Nothing in a TV is drawing 50A and they didn't put that in there to be generous with ratings.

At home I have a calibrated DC current source of 80A and an AC one of 100A.  I'll see what easy current shunts can be made with these in November when I get back.