About this post
With this article, I would like to further complete the series on current sensors with the MAX471. One or the other regular reader may already be bored – but I want to have the most important current sensors treated all. The blog shall also serve as a reference tool.
Technical features of the MAX471
The heart of the MAX471 modules is the actual MAX471 IC. The data sheet can be found here. The MAX471 is designed to measure currents up to 3 amperes. Internally, it uses a shunt (= small resistor for current measurement) of 35 milliohms, through which the current to be measured is sent. The MAX471 amplifies the voltage drop across the shunt and outputs it to the OUT pin. The voltage at OUT is always positive regardless of the current direction.
I found two versions of MAX471 modules that are a little different in their design and properties:

First of all, however, the similarities. Both modules have no connection for a power voltage. The MAX471 takes the power required for itself from the circuit to be measured. The modules are integrated into the circuit via their RS+/RS- or VIN / VOUT connections. The voltage must be in the range of 3 to 36 volts. This means that the MAX471 must be connected on the high-side, i.e. on the V+ side.
The bare MAX417 has an additional shutdown pin that can be used to put it into a sleep mode. The modules unfortunately don’t use that pin.
The most important data at a glance
- Maximum current: 3 amperes.
- Voltage range: 3 – 36 volts.
- Power consumption: < 100 microamperes.
- in sleep mode (IC only): < 18 microamperes.
- Shunt: 35 milliohms (internal).
- Sensitivity: approx. 1 volt / ampere.
Differences between the MAX471 modules
Model at the top left (purple module):
- Current connections: RS+ / RS-
- Signal: OUT
- SIGN: Indicates the current direction
Model at the top right (red module):
- Current connections: VIN / VOUT
- Signal 1 (1 Volt / ampere): AT
- Signal 2 (0.2 volts / ampere): VT
- The SIGN pin is not used
The signal 2 is generated by a voltage divider on the module from the signal 1. The voltage divider consists of the 30 kOhm and the 7.5 kOhm resistors, which you can see on the module.
Connecting the MAX471 to the Arduino
Wiring
This is what your circuit for the purple module might look like if you are using an Arduino UNO:

The OUT signal is read at the analog input A0. The SIGN pin is an open collector input. It is closed when the current flows from RS+ to RS- and is open when current flows in the other direction. You can check this by attaching a pull-up resistor and then reading it via digitalRead(). A HIGH or 1 would indicate that the current is flowing from RS+ to RS-
The wiring of the alternative red module is no longer a surprise. Most are more likely to use the more sensitive AT output than VT.

Calibration
If it doesn’t matter that much, you can just start now and determine the current according to this formula:
I\,[\text{mA}]=analogRead(A0)\cdot\frac{5000}{1023}
If you want to measure more accurately, you can calibrate your MAX471 with your trusted ammeter. In my experience, most multimeters provide fairly precise values. And if you stay below one ampere in your current measurements, you can increase the resolution of the Arduino A/D converter with analogReference(INTERNAL)
. This causes the Arduino UNO or the ATmega328P to use an internal 1.1 volt source as a reference. Simply put, an analogRead result 1023 no longer corresponds to 5, but 1.1 volts.
To create a calibration curve, you can use devices with different current consumption that you insert into the circuit. To read out the A/D converter I used the following sketch:
void setup() { Serial.begin(9600); analogReference(INTERNAL); } void loop() { unsigned int rawVal = 0; for(int i=0; i<25; i++){ rawVal += analogRead(A0); delay(10); } float meanRawVal = (rawVal / 25.0); Serial.println(meanRawVal); delay(2000); }
Since the measured values fluctuated quite strongly, 25 individual values are averaged. The voltage in millivolts is obtained by multiplying the raw values by 1.1/1023. That’s what I let Excel do for me. In addition, Excel has created a regression line (trend line) for me. I inserted the voltage values in the equation of the regression line (calculated current). The calculated current is surprisingly well in line with the measured values:


Actually, the slope of the calibration straight should be 1 mA/mV, instead it is 0.9452. That is a deviation of just over 5 percent. So, the effort is worth it if you want to measure the current accurately. I repeated it again with my favorite A/D converter, the ADS1115. The calibration line had a slope of 0.948. It all fits together pretty well.
The complete power and power sensor
Now you can use the calibration line to determine currents. You can also use the current sensor to determine the consumer’s power P. All you have to do is measure the voltage on the consumer’s V+. You already know the current (called bus current).
P = U_{V_{+}}\cdot I_{Bus}
But beware: if the power source provides a voltage greater than 5 volts for the consumer, you absolutely need to set a voltage divider between V+ (consumer) and A1 (Arduino). Otherwise you will destroy the Arduino!

The complete sketch probably doesn’t need much more explanation, except for one point. The reference for the A/D converter changes in the main loop between 5 volts (DEFAULT) and 1.1 volts (INTERNAL). After switching to 1.1 volts, I had initially detected strangely low values. This effect can be counteracted by performing a dummy analogRead()
, followed by a short delay
(line 18-20).
const int outPin = A0; const int busPin = A1; const int signPin = 8; void setup() { Serial.begin(9600); Serial.println("MAX471 Strom- und Leistungssensor"); Serial.println(); } void loop() { float voltage = 0.0; unsigned long rawVal = 0; analogReference(INTERNAL); /* After switching you have to execute a dummy analogRead, followed by a short */ rawVal = analogRead(outPin); rawVal = 0; delay(10); for(int i=0; i<25; i++){ rawVal += analogRead(outPin); delay(10); // 25 measurements to reduce noise } voltage = (rawVal/25.0) * 1100.0 / 1023.0; Serial.print("V Out [mV]: "); Serial.println(voltage); float current_mA = voltage * 0.9452 + 1.0544; // Calibration parameters Serial.print("Busstrom [mA]: "); // Bus current Serial.println(current_mA); Serial.print("Stromrichtung: : "); // Current direction if(digitalRead(signPin)){ Serial.println("RS+ -> RS-"); } else{ Serial.println("RS- -> RS+"); } analogReference(DEFAULT); voltage = analogRead(busPin) * 5.0 / 1023.0; Serial.print("Busspannung [V]: "); // Bus voltage Serial.println(voltage); float power_mW = (voltage * current_mA); Serial.print("Leistung [mW]: "); // Power Serial.println(power_mW); Serial.println("-------------------------------"); delay(2000); }
And this is what the result looks like on the serial monitor:

I could achieve even more stable values with fluctuations of well below one milliampere by using the ADS1115 A/D converter. But the result using the Arduino A/D converter is not bad either.
Acknowledgement
As usual, I used Pixabay again for parts of my post picture:
- I took the magnifying glass from OpenClipart-Vectors.
- The already frequently used electricity meter is from the free-photos section.