How to Design a Circuit to Make Your Microcontroller Read Any Current

by Fab64 in Circuits > Arduino

2434 Views, 3 Favorites, 0 Comments

How to Design a Circuit to Make Your Microcontroller Read Any Current

Screenshot 2023-01-05 at 11.41.33 AM.png
HighSideCurrentMeasurement.png
LowSideCurrentMeasurement.png

Almost any microcontroller can measure analog voltages, but how can it measure currents?

The typical approach to measure a current is to insert a very low value sensing resistor, measure the voltage across it and calculate the current through the Ohm's law (I = V / R).

The sensing resistor can be placed in two different places:

  • between the power supply and the circuit under measurement (high side measurement) 
  • between the circuit under measurement and the ground (low side measurement) 

In both cases the sensing resistor has to be very low (to avoid altering the circuit under measurement), the voltage across it is very low and then it's not easy to measure. The OpAamp circuit provides the sufficient signal amplification compatible with the ADC used to read the voltage.

Low side measurement has the advantage that even with large currents the voltage across the burden resistor is relatively low. Hence the common-mode voltage is slightly above the ground. The used OpAmp can have a low CMRR (common-mode rejection ratio). On the other side, the sensing resistor change the ground potential of the circuit under measurement, some circuits may be effected from this. Moreover, the sensing resistor can generate ground loop issues leading to noisy circuits.


Interested in measuring voltages?: How to Design a Circuit to Make Your Microcontroller Read Any Voltage

Identify the Circuit and Make the Math Yourself

Let suppose to have to measure the current flowing through a circuit which is powered at 10 V and which can drain at most 1A, using an Arduino.

The burden resistor can be set at 1ohm. At the maximum current the voltage across the sensing resistor will be:

R x I = 1ohm x 1A = 1V

This is a voltage that can easily read using Arduino but the circuit under measurement will be actually powered at 9V instead of 10V:

Vcc = VBurden + Vdut

Vdut = Vcc - VBurden = 10V - 1V = 9V

Some circuits may stop working if underpowered of 1V.

Let's try a smaller sensing resistor: 0.1 ohm, the voltage across it will be:

R x I = 0.1ohm x 1A = 0.1V

and:

Vdut = Vcc - VBurden = 10V - 0.1V = 9.9V

Now the circuit is powered at 9.9V which is almost exactly 10V but:

  1. reading 0.1V with Arduino with a reasonable precision is almost impossible
  2. connecting two Arduino's ADC pin across the sensing resistor means that the voltage at one pin is 10V and at the other pin is 9.9V. That is much more of the acceptable 5V. DON'T DO THAT!

This Instructable will answer the two following questions: Which is the right circuit to amplify the very low voltage across the sensing resistor and respecting the maximum voltage range for the Arduino's ADC inputs? How to calculate the right values of the components?

The Signal Conditioning application can be used to avoid wasting time in choosing the right circuit (which depends on input and output ranges) and making many tedious calculations (which might lead to mistakes).

Entering the maximum current to measure, the maximum acceptable voltage across the border resistor and the output voltage range, the application calculates the values of the resistors of the amplification circuit.

Disclaimer: The Signal Conditioning is for sale ... and I am its developer!.

Signal Conditioning is available on the App Store for Mac, iPhone and iPad (here)

With the app you will be able to change the input current or the burden voltage and recalculate the circuit in a matter of seconds - no calculations needed!

Often the calculated resistor values do not match the standard values, the application will allow to evaluate the impact on measurements obtained using the standard resistors values instead of the ideal calculated ones.

How to Use the Signal Conditioning App

A recap of the problem: how to measure a 1A current drained by a circuit powered at 10V using Arduino analog inputs which only accept voltages in the range of 0 รท 5V.

  • Lets start by running the Signal Conditioning app
  • Go to the Current Measurement section
  • In the Input Range section enter 1 in the Full Scale field
  • In the Output Range section enter 5 in the Full Scale field
  • Enter 0.1V in the V shunt Max (this is the voltage across the sensing resistor at the maximum current). The app has already calculated all resistors' values. It is better to decrease the value of R2 to 1K to reduce the the circuit noise (more here) which leads to a loss in precision. Arduino, given its low ADC precision, is not very much impacted by noise but it is still something to keep in consideration.

The app will compute eventually the values of R3=R5:

  • R3=R5: 50K

Click on Use Calculated Values and by entering the values of the input signal (Iin) the app will subsequently calculate the values at the circuit output. In the same way, entering an output value (Vout) (which can be measured using Arduino) the app is able to calculate the actual current at the input circuit.

In case R2 or R5 are not easily obtainable from standard values, standard values can be used instead and the application shows the relative error.

Assume using 12.2K instead of the calculated value. Enter 49.9K in the R3=R5 input field. Now, entering the corresponding values of In or Vi the app will calculate the actual values and the relative error:

Iin = 0.5 -> ideal Vout = 2.5V, rounded Vo: 2.495 (@R3=49.9K) with a relative error of 0.20%.

The app will allow to tweak the resistors values to get the best results in a matter of minutes!

Entering the VBus = 10, the app calculates the Common Mode voltage applied at the OpAmp's inputs: 9.8V.

Is the circuit design complete? Unfortunately, not. There are some additional design decisions to make:

  • The adequate OpAmp
  • The OpAmp supply voltage
  • The Voltage Source

Let's go through them one by one.

Choosing the OpAmp

he best option would be to choose a input and output rail-to-rail OpAmp with a low offset voltage.

A rail-to-rail OpAmp can accept input voltages up to the supply voltage and the output voltage can go up to the supply voltage without saturating. In other words, rail-to-rail OpAmp operates linearly with input and output voltages up to the supply voltages.

The OpAmp is a differential amplifier, hence when both its inputs are at the same voltage, the output should be 0. The offset voltage is the actual voltage at the output when the inputs have the same voltage.The lower the better.

An OpAmp option would be the OPA197. Yet, many many other OpAmps with even better characteristics are available.

They are not cheap and usually they are not ready to hand.

Let's suppose that a cheap general purpose Operational Amplifier is available: LM324N.

The datasheet states that the output swing is not rail-to-rail and the offset voltage is about 2mV.

Choosing the Supply Voltage

Since the output has to swing between 0V and 5V, the OpAmp has to be powered with a single voltage. Datasheet states that the output voltage can be up to Vp - 1.4V, the supply voltage has to be at least 7V to have some margin.

The maximum LM324N's common mode voltage (VCM) is VCC - 2V so the OpAmp has to be powered at 12V.

The Complete Circuit

Screenshot 2023-01-05 at 11.27.52 AM.png

The complete circuit diagram is shown in the picture. Note that the two decoupling capacitors should be placed as near as possible to the supply pins of the LM324N.

Important Note:

The resistors' values shown in the circuit diagram are only for Arduino boards which accept up to 5V at their analog inputs (Uno, Nano, Mega, etc.). Other Arduino boards like Zero, Mkr, Nano 33, etc. accept only up to 3.3V.

In the latter case, the tutorial is still valid but the output range values entered into Signal Conditioning have to be changed accordingly. Check out the boards specs before connecting the Arduino board.

Unused Amplifiers

image.png

In the circuit, only three out of four available amplifiers are used. To avoid the risk of oscillations and instability, best practice suggests not to leave unused amplifier unconnected. The picture shows how to safely connect the unused amplifier.

Power Supply

Screenshot 2023-01-05 at 11.26.24 AM.png

Everything seems fine so far, but the circuit has to be powered with 7V, two options are available:

  1. Use a wall power adapter which supplies 7V
  2. Usa a DC-DC (AKA step-up or boost) converter to generate the 7V from a lower voltage

Boost converters can be easily bought on-line for a few dollars (e.g., google "MT3608" but any other boost DC-DC converter will still do the job).

The picture shows how to connect the DC-DC converter, the conditioning circuit and the Arduino board.

Keep in mind that DC-DC converter are intrinsically noisy and may affect the precision of your measurements. For optimal measuring results use a linear dual power supply to power up the conditioning circuit.

Testing the Circuit Using Arduino

Arduino ADC normally uses the supply voltage as reference. This makes the measurements not very precise, because the actual supply voltage is not 5V and it can get lower depending on other circuits wired to Arduino.

A simple solution is measuring the actual supply voltage (between ground and V5 pin) and using that voltage in the conversion formula.

Alternatively, an external 5V reference voltage can be used (wired to external pin) or even better an external ADC with a higher resolution. ADS1115 can also be an option.

The provided code shows how to get the measured voltage staring from the ADC reading.

In the Arduino code using the exact value of the actual resistors, instead of the calculated values, provides better readings.


Different Input Range / Different Out Range?

Using the Signal Conditioning app, changing to a different input range or a different output range means just entering new numbers and replacing the resistors with the new ones calculated by the app.

Reading the Measurements Without Using the Arduino IDE Console

Arduino and the signal conditioning circuit can be used as an additional bench instrument (you can never have enough!). To do that, there are a couple of options:

  1. Add a Display to directly read the measurements (plenty of tutorials available online)
  2. Use a macOS or iOS application wireless connected to the microcontroller. Take a look at these other tutorials:
  3. Control Arduino from your iOS Device and Apple Watch
  4. Cheap IOT Device in Minutes and Without Writing Any Code Using Raspberry Pico Pi W

Using Arduino Manager a wireless measurements device can be created in minutes just adding a cheap bluetooth BLE adapter like HM-10 or HM-19, but there are many other options in terms of microcontrollers and communication devices that can be used. Check it out.