Sensors (ACS712, MAX417) shows strange values

Hello!

I just started with Arduino and made some test with my board and sensors. I copied most of the code from tutorials and tried to make a first example.

Aim: test my voltage and current sensors

Build: connect a LED and resistor (1200 Ohm) to 3,3V and Ground of the Uno board. “Minus” goes to the LED, then to the resistor, is going through the ACS712 current sensor (20A-type), and then via the MAX471 back to “Plus”

Voltage (DC 0-25V): is measured above 3.3V-connections, with the sensor connected to 5V of the Arduino. The reading is 3280 mV, so I am satisfied (FLUKE shows 3280 mV@3.3 and 4.755@5V).

Current (ACS712, MAX471): both show different values, also compared to my FLUKE which measures 1.3 mA when I connect it in series.

Output

DC025: 3230.29 mV   ACS712: -1.52 mA   V_out_ACS712: 2331.06 mV   MAX471: 2.35 mA   V_out_MAX471: 2372.86 mV   
DC025: 3233.77 mV   ACS712: -1.52 mA   V_out_ACS712: 2345.00 mV   MAX471: 2.35 mA   V_out_MAX471: 2382.14 mV   
DC025: 3232.61 mV   ACS712: -1.49 mA   V_out_ACS712: 2340.35 mV   MAX471: 2.35 mA   V_out_MAX471: 2340.35 mV

So, what am I doing wrong? :confused:
The Arduino is connected via USB, not DC-voltage.

// Arduino
float V_5V = 4.755;

// DC025
int analogInput_DC025 = A0;
float V_out_DC025 = 0.0;
float V_in_DC025 = 0.0;
float V_in_DC025_temp = 0.0;
float R1_DC025 = 30000.0; // intern resistor R1
float R2_DC025 = 7500.0; //  intern resistor R2
int Read_DC025 = 0;

// ACS712
int analogInput_ACS712 = A1;
float V_out_ACS712 = 0.0;
float I_in_AS712 = 0.0;
float I_in_AS712_temp = 0.0;
int mVperAmp = 100; // use 185 for 5 A, 100 for 20A and 66 for 30A Module
int ACSoffset = 2500; // offset in mV
int Read_ACS712 = 0;

// MAX471
int analogInput_MAX471 = A2;
float V_out_MAX471 = 0.0;
float I_in_MAX471 = 0.0;
float I_in_MAX471_temp = 0.0;
int Read_MAX471 = 0;

int count = 0;

void setup(){
   pinMode(analogInput_DC025, INPUT);
   pinMode(analogInput_ACS712, INPUT);
   pinMode(analogInput_MAX471, INPUT);
   Serial.begin(9600);
}

void loop(){

  // setting values back
  count = 0;
  V_in_DC025_temp = 0.0;
  I_in_AS712_temp = 0.0;
  I_in_MAX471_temp = 0.0;

  // making average of 100 values
  while (count<100){

   // read the DC025 at analog input
   Read_DC025 = analogRead(analogInput_DC025);
   V_out_DC025 = (Read_DC025 * V_5V) / 1024.0;
   V_in_DC025 = V_out_DC025 / (R2_DC025/(R1_DC025+R2_DC025)); // voltage dividor on DC025
   V_in_DC025_temp = V_in_DC025_temp + V_in_DC025;
   
   // read the ACS712 at analog input
   Read_ACS712 = analogRead(analogInput_ACS712);
   V_out_ACS712 = (Read_ACS712 * V_5V) / 1024.0 * 1000; // voltage-equivalent in mV
   I_in_AS712 = ((V_out_ACS712 - ACSoffset) / mVperAmp);
   I_in_AS712_temp = I_in_AS712_temp + I_in_AS712;
  
   // read the MAX471 at analog input
   Read_MAX471 = analogRead(analogInput_ACS712);
   V_out_MAX471 = (Read_MAX471 * V_5V) / 1024.0; // voltage-equivalent in V
   I_in_MAX471 = V_out_MAX471;
   I_in_MAX471_temp = I_in_MAX471_temp + I_in_MAX471;
  
   count++;  
   //delay(1);

  }

// getting average over 100ms # correction-factor 1 compared to measurement with voltmeter
V_in_DC025=  V_in_DC025_temp / 100 * 1;
I_in_AS712=  I_in_AS712_temp / 100 * 1;
I_in_MAX471=  I_in_MAX471_temp / 100 * 1;
   
Serial.print("DC025: ");
Serial.print(V_in_DC025 * 1000,2);
Serial.print(" mV");
Serial.print("   ");

Serial.print("ACS712: ");
Serial.print(I_in_AS712,2);
Serial.print(" mA");
Serial.print("   ");

Serial.print("V_out_ACS712: ");
Serial.print(V_out_ACS712,2);
Serial.print(" mV");
Serial.print("   ");

Serial.print("MAX471: ");
Serial.print(I_in_MAX471,2);
Serial.print(" mA");
Serial.print("   ");

Serial.print("V_out_MAX471: ");
Serial.print(V_out_MAX471*1000,2);
Serial.print(" mV");
Serial.print("   ");

Serial.println("");

}

Steve

You are doing okay. I will write down a lot of notes, and you can decide what to do with it and how to make it better. Is that okay ?

Thank you for the good photos :smiley:
I like that you work with real units in your sketch (Volt, Ampere, Ohm), but why the mV ? I think it is easier to use Volts everywhere without the milliVolts.

When doing calculations with float numbers, then I prefer to use float for everything. I suggest to make your 'mVperAmp' and 'ACSoffset' float as well.
Since almost everything will be in float, you can tell the computer to convert the value from the analogRead() into float. I prefer to tell the compiler what to do, instead of guessing that the compiler will do the right thing.

int a;
float z;
a = 3;
z = (float) a;
Read_DC025 = analogRead(analogInput_DC025);
V_out_DC025 = ( (float) Read_DC025 * V_5V ) / 1024.0;

Try to avoid to send to much text to the serial port. Once the output buffer is filled, the Arduino becomes very slow (maybe 100 times slower).
You can add a delay of 200 ms or 500 ms at the end of the loop().
You could set the baudrate to 115200, but then you must also do that for the serial monitor of the Arduino IDE.

The analogRead() may be used without pinMode(..., INPUT). See: analogRead() - Arduino Reference.

The analogRead() has a reference voltage. It is by default the 5V. When you use the USB to power the Arduino board, then the 5V varies, and so will the returned value by analogRead().
To measure a voltage with a 'voltage divider', you better use the internal reference of 1.1V: analogReference() - Arduino Reference.

When measuring a sensor that also uses the 5V as reference (the ACS712), then you should use the 5V as reference.
A ACS712 is noisy; not stable when there is no current; very sensitive for currents through wires nearby and magnetic fields or metals nearby.
A 20A ASC712 can be used to measure 1A, maybe 100mA. However, 1.3mA is far too small for that sensor.
You also have to determine what value it gives with no current. It outputs a voltage somewhere in the middle (that is about 2.5V) with no current.

Measuring a current with a shunt resistor is better. The MAX471 has an internal shunt register.
It measures up to 3A with 2% accuracy: MAX471 Precision, High-Side Current-Sense Amplifiers - Maxim Integrated.
Up to 3A with 2% means that it is accurate to 60mA. That is still a long way from the 1.3mA that you want to measure.

Advanced note: When you measure the current with the multimeter, then the multimeter itself will influence the current in that circuit. Since you use 3.3V and led with a forward voltage of about 2V, then there is only about 1.3V over the resistor. Everything you add or remove (ACS712, MAX471, multimeter) will influence that little current.

A I2C sensor that is compatible with 5V (for your 5V Uno board) does not have the trouble with the analog reference.
This is a often used current sensor: INA219 High Side DC Current Sensor Breakout - 26V ±3.2A Max [STEMMA QT] : ID 904 : $9.95 : Adafruit Industries, Unique & fun DIY electronics and kits. You could even replace the shunt resistor with a higher value to measure very small currents.
Using the I2C bus is a step forward. You would have to install libraries (use the Library Manager from the Arduino IDE).

When you don't want to use the I2C bus yet, then try your sensors with more current.

Do you have a LDR ? That is easier to start with. Just a 3 cent LDR and a 10k resistor to measure the amount of light.

Tip: Buy an extra Arduino board as a spare. You might destroy one when you start using 12V and motors.

Thank you for your comments. I will successively work on them :slight_smile:

Steve