Wednesday 28 October 2015

INA117P Current Measurement

A blog reader asked me to help them design a current sensing circuit.  They weren't too specific about the requirements of the measurement output some I'm going to guess it was the ADC input to a microcontroller.  The measurement side was specified as being able to measure 5V at 30 mA from what is referred to as a low wind speed energy harvesting system...I'm guessing they are talking about some sort of simple wind powered generator.

They have asked me to design a circuit using the INA117P which is a difference amplifier made by Texas Instruments.  It has many applications including current measurement.  It's datasheet describes its function as a "precision unity gain difference amplifier".  That means that it measures the difference between it's inputs perfectly without adding any gain at the output.  The information about the device itself can be found from the datasheet:

INA117P datasheet from TI

If we read through the datasheet we can find some helpful application schematics which should provide all the information we need along with the standard specification and ratings information. The circuit in figure 5 is the one we need to apply to our requirements:

Let us first do some Mathematics applying Ohms Law:

V / I = R (Load)

So to calculate the load we have:

5 volts / 0.03 amps = 166 Ohms which is the load being applied.

We can now design the circuit:


The circuit is fairly standard.  The current to be measured from the voltage V1 (the output from the wind powered generator) is passed through a 1 Ohm 'sense' resistor which should be a high precision resistor.  The load is then connected after that which is as calculated 166 Ohms.  The sense resistor is also connected to the differential inputs of the INA117P - the differential unity gain amplifier.  This device measures the difference between the voltages on those pins and provides the output which because the sense resistor is 1 Ohm will be the current flowing in the load.  To simplify matters I used a voltmeter to show that the voltage at the output will be 0.03 volts which is the same value as 0.03 Amps - we have made a circuit which converts current in the load to voltage at the output of the differential amplifier.  The voltmeter can be removed and the output of the INA117P can be connected directly to a microcontroller ADC input and used to display or monitor current - whatever the designer requires...

The issue with the INA117P is that in order for it to work correctly it requires both a positive supply and a negative supply.  This is often difficult to achieve with standard microcontrollers which normally only use a positive 5 volt supply, particularly the arduino...however here is a trick which can be used to make a +/- 5V supply...if you are in a pinch....

Just make sure the GND connection of the power supply is not connected to chassis ground or earth - The circuit won't work and at the worst the power supply could go into current limit...which might damage the supply or cause it to shut down briefly.

Once we have our circuit and the +/- supply all that's needed is to connect it up to a microcontroller and presto we have a method of monitoring the current from the wind generator.

Here is the full circuit:


The parts list for this circuit is below:

1x Arduino R3 or similar microcontroller
1x INA117P Differential Unity gain amplifier
1x 1Ohm Precision current sense resistor
2x 100k Ohm resistors
2x 10 uF Capacitors
2x 5mm Screw terminal connectors

Once you have all of the components connected up and wired up as shown in the schematic we will need to write some code to control the arduino and get it to perform the function we want:

Read the voltage presented at pin A0, convert it from a raw bit value into volts and then display that voltage (labelled) as current via the serial terminal or on an LCD display or whatever we need - No problems.  To be correct and to ensure we get correct values lets display the average of 100 samples to reduce noise issues:

//Alex's INA117P Current Meter test code

const int analogIn = A0; //output of INA117P is connected to A0

int RawValue = 0;  // The raw analogue value

// Define the number of samples to keep track of.  The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input.  Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 100;

int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

float Amps = 0;

void setup()
{
  Serial.begin(9600);
  Serial.println("INA117P Current Meter Test");
  
  // initialize all the readings to 0: 
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
  readings[thisReading] = 0;   
}

void loop()
{
  
  // subtract the last reading:
  total= total - readings[index];         
  // read from the sensor:  
  readings[index] = analogRead(analogIn); 
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array:  
  index = index + 1;                    

  // if we're at the end of the array...
  if (index >= numReadings)              
  // ...wrap around to the beginning: 
  index = 0;                           

  // calculate the average:
  average = total / numReadings;         
    
  RawValue = average;
  
  Amps = (RawValue / 1023.0) * 5; // convertaveraged raw value to mV 
  
  Serial.print("Raw Value = " ); // shows pre-scaled value
  Serial.print(RawValue);
  Serial.print("\t A = "); // shows the current measured
  Serial.print(Amps, 3); // the '3' after voltage allows you to display 3 digits after decimal point
  delay(100);

}

I haven't actually got an INA117P so I can't test this circuit...But don't worry I know it will work - the simulation perform came out perfectly and I have built and used many similar circuits.  

Let me know if you try this and it doesn't work - Cheers for now - Langster!

Tuesday 13 October 2015

Voltage Measurements Using the Arduino

I often need to make voltage measurements using my arduino.  I recently built a voltage, current and temperature data logger for testing lithium batteries and I needed to be able to measure 50 Vdc safely into the Arduino although any ADC input from a microcontroller could be substituted.

Rather than reinvent the wheel I decided (possibly foolishly) to use a voltage measurement breakout board:

I bought mine from Hobby Components but they can be obtained everywhere:


To be fair I didn't really look into the module properly as I was in a rush.  The circuit itself is a simple 5:1 voltage divider and a screw terminal and some header pins.  For the price of £1.99 I shouldn't complain.  The circuit is below for those that are interested.


Not sure why they added the Banana connector footprint...but hey ho, Or why they used a 3 pin connector on the output...as one of the pins does nothing at all...

The circuit is a 5:1 voltage divider.  So a person using this circuit can measure voltage signals ranging from 0 volts to 25 volts.  If you were to change the resistor values you can then change the voltage measurement range.

Here is some simple code to get this to work with an arduino with the measurement output connected to A0 on the arduino:

/*
DC Voltmeter Using a Voltage Divider
*/

int analogInput = A0;  // Read the voltage from the divider on A0 
float vout = 0.0;      // variable for the calculated voltage 
float vin = 0.0;       // variable for the resulting voltage
float R1 = 30000.0;    // variable to store the value of R1  
float R2 = 7500.0;     // variable to store the value of R2
int raw = 0;           // variable to store the raw ADC measurement

void setup(){
   pinMode(analogInput, INPUT);  // set pin A0 to be an input
   
   Serial.begin(9600);           // start the serial monitor
   Serial.print("DC VOLTMETER"); // display a welcome message
}
void loop(){
   
   // read the value at analog input A0
   // calculate the voltage from the raw adc value
   // account for the voltage divider
   // Display the result

   raw = analogRead(analogInput);
   vout = (value * 5.0) / 1023.0; 
   vin = vout / (R2/(R1+R2)); 
   
   Serial.print("INPUT V= ");
   Serial.println(vin,2);
   delay(500);
}

I tested the above code and it works perfectly well and this board can be used to make voltage measurements.  My concerns with it are that it has no protection against a person trying to measure too much voltage or a signal too high in current.  With the above breakout board an over voltage or over current event will damage the ADC input of the arduino or microcontroller being used.  The maximum current an Atmel 328p pin can accept according to the datasheet is 20 mA.  

If we apply more than 25 Volts to input of the voltage divider the instantaneous current presented to the A0 input pin could be more than 20 mA and if the voltage is really high it will give us an incorrect reading.  It would be better if we protected the ADC input from over-voltage and current events and then ensure our circuit and our micro-controller ADC inputs work perfectly in any condition, fault or normal.

To protect against over current events we need to add a series resistor.  I'm choosing to add a 22 ohm resistor in series.  This prevents the current being presented to the ADC input ever becoming greater than 20 mA even if 2500 volts are applied (by mistake) to the voltage divider input.
Next we are going to add a low value capacitor (100 pF).  This takes some of energy out a high voltage transient (pulse) like an electrostatic discharge and also provide a small amount of filtering to the circuit.
Finally lets ensure that the voltage applied to the ADC input of the microcontroller is always about 5 volts.  This is achieved by adding some clamping diodes.  These are simple signal diodes - 1N4148 diodes will do...Here is the final circuit.
Just to prove the function of the circuit and what achieves for us lets simulate the different error conditions to show what happens.  I'm going to show pictures rather than a full video.

Lets set some parameters.  Lets assume by mistake someone tries to measure a voltage and by mistake they apply 2500 Vdc...This is what gets applied to the ADC input of the arduino.  It might not destroy it but it would certainly damage the microcontroller...
Lets add the current limiting 22 Ohm series resistor, which doesn't affect the measurement but reduces the current presented to the load (the ADC input pin).
Lets now add the capacitor to the circuit.
Finally lets add the clamping diodes...which incidentally have the most effect!

What the simulation clearly shows is that if by mistake 2500 volts was applied to the voltage divider with the clamp diodes, series resistor and capacitor only 6.37 volts and 637 nA will be applied to the ADC input.  The voltage divider will still work as intended though and nothing will be damaged on the microcontroller - good things all round.

The point I'm getting at is that if a voltage divider circuit is used to measure voltages on an arduino or any other microcontroller then without the above components to provide protection bad things may happen.  This is why the 25 Volt measurement breakout boards are not the best circuit.  It would not cost much more to apply the protection components.

Well that's all for now people - Enjoy and hope this post was helpful.  I might make a few voltage sensor breakout boards for sale if demand is high enough - I know I'll need some from time to time.

Cheers - Langster!