ACS 712 sensor error in measuring current

Hi, I'm trying to use the ACS 712 sensors to measure current.

ACS712ELC-30A

I got the 30 amp version to make the current testing rig future proof.
Most of what I'm currently measuring though will be under 1 amp.
I didn't know that the analog values represent a certain set of mV values which are different based on each sensor model.

I changed the mVperAmp value to the value used for the 5 amp version of the sensor.
Although I don't think this is a practical fix I wanted to try it out.
Based on surfing the web and looking at other forum posts the values below are used to measure the current on the respective sensor models:

//use 185 for 5A Module, 100 for 20A Module, and 66 for 30A Module

I have 2 main issues:

  1. My current ratings are not fluctuating on the serial monitor when the cycle is turning on.
    I've offset the ACSoffset value to get an initial current rating of ~ 0 amps, but even with the ports on
    and one solenoid attached to it, the current does not fluctuate.

  2. I'm turning on and off 8 relays at the same time.
    With my current code setup when the cycle count is over the relays turn off.
    However, with the code setup like shown below my cycle count is off by 1.

If I start the cycle count with the port on then the count is right but it won't turn off after the cycle is
over. I tried placing a port off code outside of the for loop and it still wouldn't turn off. So basically the
relays stay on and I don't want that after the cycle is complete.

    PORTA = B00000000;
    delay(TOff); //delay between turning off each relay
    PORTA = B11111111;
    delay(TOn); //delay between turning on each relay
#include <LiquidCrystal.h>
#include <MenuBackend.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to

const int rs = 8, en = 9, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;

#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5

// read the buttons
int read_LCD_buttons() {
  adc_key_in = analogRead(8);
  // read the value from the sensor
  // my buttons when read are centered at these values: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  if (adc_key_in < 50)   return btnRIGHT;
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;
  return btnNONE;  // when all others fail, return this...
}

/****************************************************************************/

int TOn = 1000; //analogRead(1)*4;   // Adjust delay time in milliseconds to turn relay on/off
int TOff = 200; //analogRead(2)*4;

/* Measuring DC Current Using ACS712 */

double mVperAmp = 185; // use 185 for 5A Module, 100 for 20A Module, and 66 for 30A Module
float ACSoffset = 2470.345;

double RawValue1 = 0;
double RawValue2 = 0;
double RawValue3 = 0;
double RawValue4 = 0;
double RawValue5 = 0;
double RawValue6 = 0;
double RawValue7 = 0;
double RawValue8 = 0;

double V1 = 0;
double V2 = 0;
double V3 = 0;
double V4 = 0;
double V5 = 0;
double V6 = 0;
double V7 = 0;
double V8 = 0;

double Amps1 = 0;
double Amps2 = 0;
double Amps3 = 0;
double Amps4 = 0;
double Amps5 = 0;
double Amps6 = 0;
double Amps7 = 0;
double Amps8 = 0;

const int S1 = A0; // Analog input pin that sensor is attached to
const int S2 = A1;
const int S3 = A2;
const int S4 = A3;
const int S5 = A4;
const int S6 = A5;
const int S7 = A6;
const int S8 = A7;

void setup () {
  lcd.begin(16, 2);   // set up the LCD's number of columns and rows:
  lcd.setCursor(0, 0); // set printing position on lcd screen, currently that is row 0, column 0)
  lcd_key = read_LCD_buttons();  // read the buttons
  Serial.begin(9600);
  pinMode(S1, INPUT);
  pinMode(S2, INPUT);
  pinMode(S3, INPUT);
  pinMode(S4, INPUT);
  pinMode(S5, INPUT);
  pinMode(S6, INPUT);
  pinMode(S7, INPUT);
  pinMode(S8, INPUT);

  DDRA = B11111111; // set PORTA (digital 22-29) to outputs

  int maxnumber = 10; // set cycle count

  for (int count = 0; count < maxnumber;) //Counter will stop counting after certain amount of cycles
  {
    PORTA = B00000000;
    delay(TOff); //delay between turning off each relay
    PORTA = B11111111;
    delay(TOn); //delay between turning on each relay

    RawValue1 = analogRead(S1);
    RawValue2 = analogRead(S2);
    RawValue3 = analogRead(S3);
    RawValue4 = analogRead(S4);
    RawValue5 = analogRead(S5);
    RawValue6 = analogRead(S6);
    RawValue7 = analogRead(S7);
    RawValue8 = analogRead(S8);

    V1 = (RawValue1 / 1023.0) * 5000; // Gets you mV
    V2 = (RawValue2 / 1023.0) * 5000;
    V3 = (RawValue3 / 1023.0) * 5000;
    V4 = (RawValue4 / 1023.0) * 5000;
    V5 = (RawValue5 / 1023.0) * 5000;
    V6 = (RawValue6 / 1023.0) * 5000;
    V7 = (RawValue7 / 1023.0) * 5000;
    V8 = (RawValue8 / 1023.0) * 5000;

    Amps1 = ((V1 - ACSoffset) / mVperAmp);
    Amps2 = ((V2 - ACSoffset) / mVperAmp);
    Amps3 = ((V3 - ACSoffset) / mVperAmp);
    Amps4 = ((V4 - ACSoffset) / mVperAmp);
    Amps5 = ((V5 - ACSoffset) / mVperAmp);
    Amps6 = ((V6 - ACSoffset) / mVperAmp);
    Amps7 = ((V7 - ACSoffset) / mVperAmp);
    Amps8 = ((V8 - ACSoffset) / mVperAmp);

    Serial.println("Amps1 = "); // shows the voltage measured
    Serial.println(Amps1, 3); // the '2' after voltage allows you to display 2 digits after decimal point

    Serial.println("Amps2 = ");
    Serial.println(Amps2, 3);

    Serial.println("Amps3 = ");
    Serial.println(Amps3, 3);

    Serial.println("Amps4 = ");
    Serial.println(Amps4, 3);

    Serial.println("Amps5 = ");
    Serial.println(Amps5, 3);

    Serial.println("Amps6 = ");
    Serial.println(Amps6, 3);

    Serial.println("Amps7 = ");
    Serial.println(Amps7, 3);

    Serial.println("Amps8 = ");
    Serial.println(Amps8, 3);

    Serial.println("");

    lcd.clear(); //clears lcd before incrementing to next number
    count++;
    lcd.print(count);
  }
}

void loop() {
}

Most of what I'm currently measuring though will be under 1 amp.

That's like trying to use a 30 pound scale to measure a few ounces. Using the proper sensor is a much better idea.

I didn't know that the analog values represent a certain set of mV values which are different based on each sensor model.

Then why would you comment, either way?

Based on surfing the web

So, you know what a link looks like, and yet you failed to post a link to your sensor. Try again.

Here is the link for the sensor:

knightridar:
Here is the link for the sensor:

https://www.amazon.com/DAOKI-Current-Sensor-Module-Arduino/dp/B00XT0PL20/ref=sr_1_1?ie=UTF8&qid=1505839180&sr=8-1&keywords=ARDUINO+CURRENT+SENSOR

So, amazon is making sensors these days. I did not know that. I, for sure, would not buy one from them since they have NO details about the sensor. All that they have is a pretty picture.

Pretty pictures are for porn magazines.

here is the link to the pdf file of the sensor:

Page 5 of 14 describes the mV/A setting used to calculate the current in the equations in the first post.

  pinMode(S1, INPUT);
  pinMode(S2, INPUT);
  pinMode(S3, INPUT);
  pinMode(S4, INPUT);
  pinMode(S5, INPUT);
  pinMode(S6, INPUT);
  pinMode(S7, INPUT);
  pinMode(S8, INPUT);

Why are you setting the mode of the digital pin that shares space with the analog pin, when using the pin as an analog pin. This CAN interfere with using the pin as an analog pin.

Arrays and for loops are your friends.

Reading from different analog pins usually requires that you read twice and throw away the first reading.

    Serial.println(Amps1, 3); // the '2' after voltage allows you to display 2 digits after decimal point

Useless comments MUST match the code!

Thinking that a 30 A sensor is going to read less than 1 A accurate to three decimal places is wishful thinking, at best.

Ok got rid of pin mode.

I am breaking the problems down into pieces.

Issue 2 is resolved. I just had to turn the ports off at the end of the for loop.

  1. I'm turning on and off 8 relays at the same time.
    With my current code setup when the cycle count is over the relays turn off.
    However, with the code setup like shown below my cycle count is off by 1.

If I start the cycle count with the port on then the count is right but it won't turn off after the cycle
is over. I tried placing a port off code outside of the for loop and it still wouldn't turn off. So
basically the relays stay on and I don't want that after the cycle is complete.

int TOn = 1000; //Adjust delay time in milliseconds to turn relay on/off
int TOff = 200; 

void setup () {

  Serial.begin(9600);
  DDRA = B11111111; // set PORTA (digital 22-29) to outputs

  int maxnumber = 4; // set cycle count

  for (int count = 0; count < maxnumber;) //Counter will stop counting after certain amount of cycles
  {
    PORTA = B11111111;
    delay(TOn); //delay between turning on each relay
    
    PORTA = B00000000;
    delay(TOff); //delay between turning off each relay
    
    Serial.print(""); //clears serial port before incrementing to next number
    count++;
    Serial.print(count);
  }
  DDRA = B00000000;
}
void loop() {
}

I've modified the code to print on the lcd.

It's really bizarre this wasn't happening before but now I am getting weird characters on the lcd screen.
Like an infinity symbol, forward slash, blank block, etc... and sometimes the count displays.

I will double check the pin connections.
I am using the D1 Robot LCD keypad shield.
https://www.dfrobot.com/wiki/index.php/Arduino_LCD_KeyPad_Shield_(SKU:_DFR0009)

#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to

const int rs = 8, en = 9, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

/**************************************************************************************/

int TOn = 1000; //Adjust delay time in milliseconds to turn relay on/off
int TOff = 200;

void setup () {

  lcd.begin(16, 2);   // set up the LCD's number of columns and rows:
  lcd.setCursor(0, 0); // set printing position on lcd screen, currently that is row 0, column 0)
  Serial.begin(9600);
  DDRA = B11111111; // set PORTA (digital 22-29) to outputs

  int maxnumber = 10; // set cycle count

  for (int count = 0; count < maxnumber;) //Counter will stop counting after certain amount of cycles
  {
    PORTA = B11111111;
    delay(TOn); //delay between turning on each relay

    PORTA = B00000000;
    delay(TOff); //delay between turning off each relay

    lcd.clear(); //clears lcd before incrementing to next number
    count++;
    lcd.print(count);
  }
  DDRA = B00000000;
}
void loop() {
}

I tested code with just text in it that remains static and it works without erroring out.

The screen only displays weird characters when the count function is displaying.

I didn't change the wiring either and I've double checked if the right wires are connected to the Arduino.

I'm wondering if it has anything to do with the relays turning on and off.
Even though I'm powering the screen with a separate 5V power supply it seems to flicker slightly as the relays turn on and off. Although I was using relays before and it was working fine with older versions of code. I tried it reuploading the older versions of code and I still get errors on the screen.

The code below works for counting and the display doesn't error out.
I'm beginning to wonder if it is the relays turning on and off.

#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to

const int rs = 8, en = 9, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  lcd.begin(16, 2);   // set up the LCD's number of columns and rows:
  lcd.setCursor(0, 0); // set printing position on lcd screen, currently that is row 0, column 0)
}

void loop() {

  int maxnumber = 10; // set cycle count

  for (int count = 0; count < maxnumber;)
  {
    lcd.clear();
    lcd.print(count++);
    delay(1000);
  }
}

I'm beginning to wonder if it is the relays turning on and off.

Unless you have snubber diodes on the relays, that is quite possible.

Hi,
Can you post a complete picture of your project so we can see your component layout.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

How are you powering the Arduino and the relays?

Thanks. Tom... :slight_smile:

Hi, I'm trying to use the ACS 712 sensors to measure current.
...

I got the 30 amp version to make the current testing rig future proof.
Most of what I'm currently measuring though will be under 1 amp.

These are hall-effect sensors - they are very noisy and imprecise and only for high
current. But they are isolated from the load which can be handy.

If you are measuring under 1A these are definitely not the sensors to use,
you want a shunt-resistor based sensor for that.

I did think of getting one of those. Really liked the resolution on the sensor below and it'll work up to 3.2 amps. I'll look for some more.

Problem is I'm setting up a system using 8 relays.
The INA219 can only be used up to a maximum of 4 sensors because of the way it's setup and it uses the SDA and SCL ports on the arduino.

Up to 4 boards may be connected. Addressing is as follows:
Board 0: Address = 0x40 Offset = binary 00000 (no jumpers required)
Board 1: Address = 0x41 Offset = binary 00001 (bridge A0 as in the photo above)
Board 2: Address = 0x44 Offset = binary 00100 (bridge A1)
Board 3: Address = 0x45 Offset = binary 00101 (bridge A0 & A1)

Hi,
Please answer post #11.

How are you powering the project?
How are you driving the relays?
What are the relays?

Thanks.. Tom... :slight_smile:

Hi powering it via:

Whole system:
24V, 21A, 500 Watt DC power supply

Arduino powered by:
12V, 5A, 24V DC to 12V DC converter hooked up to the power supply .

Relays and Current sensors powered by:
5V, 5A, 12/24V DC to 5V DC converter hooked up to the power supply.

The relays are on an 8 relay module (SONGLE brand).

You can download CAD models of the parts here:

For the 8 relay module, there are a few options but here is one link:

Hi,
Thanks for the pics, now for the circuit diagram, even a picture of a hand drawn schematic will do.
Make sure you show how your gnds are connected.

Keep your input wiring well way from your output wiring, in particular the relay board.

It looks like your relays are directly under your current sense boards.

Thanks... Tom... :slight_smile:

I am wondering if I should move this post over to the general electronics section.
Although I may still have some programming questions.

The reason why I have my ACS712 sensors right above the relays is because the wires were longer before but the wires were really becoming a hassle to organize and troubleshoot.
Also I am going to 3D print an enclosure and my print size is limited.
I am trying to keep things as close together as possible.

Are you telling me to keep input wiring far from output wiring for safety reasons?
I just realized that the relays have electromagnets. Could they have an effect on the ACS 712 sensors being mounted right above them since they are using hall sensors?

I am unsure of the schematic because I'm not sure if I wired the circuit in series with respect to the terminal blocks (although there are no resistors hooked up to the terminal blocks so is it a node???), but I will draw one out soon.

Just to give you an idea of the setup from the pictures:

I am using two separate terminal blocks to supply Vin and Gnd to supply power to the ACS 712 current sensor modules from the 5V DC converter.
(I used a multimeter and the voltage is at 5 volts but varies slightly sometimes as high as 5.5 volts when the relays turn on/off).

The 8 relay module was easy to supply power to. I am taking Vin and Gnd connections from the 5V power terminal blocks and hooking it up to the JD-VCC and Gnd connections on the module.

I am using another two separate terminal blocks to supply Vin and Gnd from the power supply to the relay module/current sensor and the ground connection gets connected to the white quick disconnect pieces in the previous post.
( Vin -->Goes from DC power supply to-->terminal blocks -->common port of relay
-->ACS 712 sensor--> ACS 712 sensor to NO port of relay--->quick disconnects)

(Gnd -->From DC power supply to -->terminal block -->to quick disconnects)

The schematic is attached.

Welcome.

Here is an update....

At first I thought the ACS712 sensors were too close to the relays or the wiring itself was too close together or it could be both things.

I moved the ACS712 sensors away from the relays and moved wiring away from the relays and the screen was displaying characters just right.

However, this didn't solve the problem.
I've noticed when the solenoid is not working or activating the cycle count is fine, but when the solenoid is working that is connected to relay #8,
I get a messed up cycle count on the LCD screen.

Weird.
I don't see how a rise in possible current for the solenoid could cause the screen to print out weird characters. The solenoid is 24V. The lcd screen has it's own separate power supply that is being fed by the 24V power supply.

#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to

const int rs = 8, en = 9, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

/****************************************************************************/

int TOn = 1000; // Adjust delay time in milliseconds to turn relay on/off
int TOff = 200; 

/* Measuring DC Current Using ACS712 */

double mVperAmp = 66; // use 185 for 5A Module, 100 for 20A Module, and 66 for 30A Module
float ACSoffset = 2448.455;

double RawValue1 = 0;
double RawValue2 = 0;
double RawValue3 = 0;
double RawValue4 = 0;
double RawValue5 = 0;
double RawValue6 = 0;
double RawValue7 = 0;
double RawValue8 = 0;

double V1 = 0;
double V2 = 0;
double V3 = 0;
double V4 = 0;
double V5 = 0;
double V6 = 0;
double V7 = 0;
double V8 = 0;

double Amps1 = 0;
double Amps2 = 0;
double Amps3 = 0;
double Amps4 = 0;
double Amps5 = 0;
double Amps6 = 0;
double Amps7 = 0;
double Amps8 = 0;

const int S1 = A0; // Analog input pin that sensor is attached to
const int S2 = A1;
const int S3 = A2;
const int S4 = A3;
const int S5 = A4;
const int S6 = A5;
const int S7 = A6;
const int S8 = A7;

void setup () {
  lcd.begin(16, 2);   // set up the LCD's number of columns and rows:
  lcd.setCursor(0, 0); // set printing position on lcd screen, currently that is row 0, column 0)
  Serial.begin(9600);

  DDRA = B11111111; // set PORTA (digital 22-29) to outputs

  int maxnumber = 4; // set cycle count

  for (int count = 0; count < maxnumber;) //Counter will stop counting after certain amount of cycles
  {
    PORTA = B11111111;
    delay(TOn); //delay between turning on each relay
    PORTA = B00000000;
    delay(TOff); //delay between turning off each relay

    RawValue1 = analogRead(S1);
    RawValue2 = analogRead(S2);
    RawValue3 = analogRead(S3);
    RawValue4 = analogRead(S4);
    RawValue5 = analogRead(S5);
    RawValue6 = analogRead(S6);
    RawValue7 = analogRead(S7);
    RawValue8 = analogRead(S8);

    V1 = (RawValue1 / 1023.0) * 5000; // Gets you mV
    V2 = (RawValue2 / 1023.0) * 5000;
    V3 = (RawValue3 / 1023.0) * 5000;
    V4 = (RawValue4 / 1023.0) * 5000;
    V5 = (RawValue5 / 1023.0) * 5000;
    V6 = (RawValue6 / 1023.0) * 5000;
    V7 = (RawValue7 / 1023.0) * 5000;
    V8 = (RawValue8 / 1023.0) * 5000;

    Amps1 = ((V1 - ACSoffset) / mVperAmp);
    Amps2 = ((V2 - ACSoffset) / mVperAmp);
    Amps3 = ((V3 - ACSoffset) / mVperAmp);
    Amps4 = ((V4 - ACSoffset) / mVperAmp);
    Amps5 = ((V5 - ACSoffset) / mVperAmp);
    Amps6 = ((V6 - ACSoffset) / mVperAmp);
    Amps7 = ((V7 - ACSoffset) / mVperAmp);
    Amps8 = ((V8 - ACSoffset) / mVperAmp);

    Serial.print("Amps1 = "); // shows the voltage measured
    Serial.println(Amps1, 3); // the '3' after voltage allows you to display 3 digits after decimal point

    Serial.print("Amps2 = ");
    Serial.println(Amps2, 3);

    Serial.print("Amps3 = ");
    Serial.println(Amps3, 3);

    Serial.print("Amps4 = ");
    Serial.println(Amps4, 3);

    Serial.print("Amps5 = ");
    Serial.println(Amps5, 3);

    Serial.print("Amps6 = ");
    Serial.println(Amps6, 3);

    Serial.print("Amps7 = ");
    Serial.println(Amps7, 3);

    Serial.print("Amps8 = ");
    Serial.println(Amps8, 3);

    Serial.println("");

    lcd.clear(); //clears lcd before incrementing to next number
    count++;
    lcd.print(count);
  }
  DDRA = B00000000;
}

void loop() {
}