Auto ranging ohmmeter using arduino.

This article is about a simple auto ranging ohmmeter using arduino. The measured resistance is displayed using a 16×2 LCD display. The circuit is sufficiently accurate and uses minimum number of external components possible. Before going into the details of this project, lets have a look at the basic resistance measurement method.

Resistance measurement.

resitance measurement

The figure above shows the circuit diagram of a simple resistance measurement scheme. Rx is the resistance to be measured. R1 is the input resistance. i is the current passing through the loop and 5V is the supply voltage. To find the unknown resistance Rx, the voltage across Rx is measured first. let the voltage across R1 be VR1. Then VR1=5-Vx.  The current i=VR1/R1=(5-Vx)/R1. Since R1 and Rx are connected in series, the current through them will be equal. So the unknown resistance Rx= Vx/i. The voltage across the unknown resistance is measured using the ADC of the arduino. To be precise, analog channel A5.

Anyway this method have a drawback. If there is great difference between the input resistance and the Rx, the result will be extremely inaccurate. This is because almost all of the input voltage will drop across the larger resistance and this provides very less information.

  • Suppose R1=10K and Rx=100 ohm. Then the voltage across R1 will be 4.95v and voltage across Rx will be 50mV and this gives less information. The sensitivity of the arduino is 4.889mV. So when we read 50mV  using the arduino ADC the result will be 10. When converted it into voltage the result will be 10 x 4.889mV =48.89mV.  Then Rx= 0.0488/((5V-48.89mV)/10000) = 98.7 ohm.
  • Suppose R1=10 and Rx=220 ohm. Then the voltage across R1 will be 4.89V and voltage across Rx will be 107mV. The corresponding digital reading will be 21. When we convert it into voltage the result will be 21 x 4.889mV=102mv. Following the calculations used in the previous case, Rx=208 ohm.

In the above two cases you can see accuracy issues. The most accurate result occurs when the Rx and R1 are as close as possible.

Auto ranging.

A scheme for estimating the value of Rx roughly and then putting a matching resistor in place of R1 is what we  need here and this method is called auto ranging. The circuit given below demonstrates auto ranging.

 arduino resistance meter Resistances R1 to R7 are the input resistors. In this scheme the free end of one resistor is held high and the free ends of other resistors are held low. The the voltage across the unknown resistance Rx is measured. Diodes D1 to D7 are used to prevent the back flow of current towards the low ends. Suppose free end of R1 is held low. If R1 and Rx are equal, then the voltage drop across Rx will be (5-0.7)/2 = 2.15 where 0.7 is the diode drop. If the voltage across Rx is less than or equal to 2.15, we can assume that Rx is less than or equal to 220 ohms. The closest value possible for the input resistance is 220 ohms and so this loop is considered for calculation. If the above condition is not satisfied, the above steps are repeated with the succeeding input resistors until we get a solution.

Circuit diagram.

ohmmeter using arduinoFull circuit diagram of the auto ranging ohmmeter using arduino is shown in the figure above.  Digital pins 1, 6, 7, 8, 9, 10, 13 of the arduino are used to switch the input resistors R1, R2, R3, R4, R5, R6, R7 respectively. Resistors D1 to D7 are used to prevent the back flow of current through the corresponding path.  D8 is the power ON indicator LED. POT R10 is used for contrast adjustment of the LCD. Resistor R9 limits the back light LED current.

Program.

#include<LiquidCrystal.h>
int vin=A5;

int t=1;
int u=6;
int v=7;
int w=8;
int x=9;
int y=10;
int z=13;

int at;
int au;
int av;
int aw;
int ax;
int ay;
int az;
int a;
double vx;
float rx;
double i;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup()
{
pinMode(vin,INPUT);
lcd.begin(16,2);

pinMode(t,OUTPUT);
pinMode(u,OUTPUT);
pinMode(v,OUTPUT);
pinMode(w,OUTPUT);
pinMode(x,OUTPUT);
pinMode(y,OUTPUT);
pinMode(z,OUTPUT);

digitalWrite(t,LOW);
digitalWrite(u,LOW);
digitalWrite(v,LOW);
digitalWrite(w,LOW);
digitalWrite(x,LOW);
digitalWrite(y,LOW);
digitalWrite(z,LOW);
}
void loop()
{

digitalWrite(t,HIGH);
digitalWrite(u,LOW);
digitalWrite(v,LOW);
digitalWrite(w,LOW);
digitalWrite(x,LOW);
digitalWrite(y,LOW);
digitalWrite(z,LOW);
delay(100);
at=analogRead(vin);




digitalWrite(t,LOW);
digitalWrite(u,HIGH);
digitalWrite(v,LOW);
digitalWrite(w,LOW);
digitalWrite(x,LOW);
digitalWrite(y,LOW);
digitalWrite(z,LOW);
delay(100);
au=analogRead(vin);
digitalWrite(t,LOW);
digitalWrite(u,LOW);
digitalWrite(v,HIGH);
digitalWrite(w,LOW);
digitalWrite(x,LOW);
digitalWrite(y,LOW);
digitalWrite(z,LOW);
delay(100);
av=analogRead(vin);



digitalWrite(t,LOW);
digitalWrite(u,LOW);
digitalWrite(v,LOW);
digitalWrite(w,HIGH);
digitalWrite(x,LOW);
digitalWrite(y,LOW);
digitalWrite(z,LOW);
delay(100);
aw=analogRead(vin);


digitalWrite(t,LOW);
digitalWrite(u,LOW);
digitalWrite(v,LOW);
digitalWrite(w,LOW);
digitalWrite(x,HIGH);
digitalWrite(y,LOW);
digitalWrite(z,LOW);
delay(100);
ax=analogRead(vin);


digitalWrite(t,LOW);
digitalWrite(u,LOW);
digitalWrite(v,LOW);
digitalWrite(w,LOW);
digitalWrite(x,LOW);
digitalWrite(y,HIGH);
digitalWrite(z,LOW);
delay(100);
ay=analogRead(vin);



digitalWrite(t,LOW);
digitalWrite(u,LOW);
digitalWrite(v,LOW);
digitalWrite(w,LOW);
digitalWrite(x,LOW);
digitalWrite(y,LOW);
digitalWrite(z,HIGH);
delay(100);
az=analogRead(vin);

if(az>=450)
{
vx=az*0.00489;
i=(5-vx-0.55)/22000;
rx=(vx/i);
}
if(ay>=450 && az<450)
{
vx=ay*0.00489;
i=(5-vx-0.55)/10000;
rx=(vx/i);
}
if(ax>=448 && ay<448 && az<448)
{
vx=ax*0.00489;
i=(5-vx-0.55)/4700;
rx=(vx/i);
}

if(aw>=439 && ax<439 && ay<439 && az<439)
{
vx=aw*0.00489;
i=(5-vx-0.55)/2200;
rx=(vx/i);
}

if(av>=439 && aw<439 && ax<439 && ay<439 && az<439)
{
vx=av*0.00489;
i=(4.8-vx-0.55)/1000;
rx=(vx/i);
}

if(au>=430 && av<430 && aw<430 && ax<430 && ay<430 && az<430)
{
vx=au*0.00489;
i=(4.5-vx-0.55)/560;
rx=(vx/i);
}

if(at>=430 && au<430 && av<430 && aw<430 && ax<430 && ay<430 && az<430 )
{
vx=at*0.00489;
i=(4.5-vx-0.55)/220;
rx=(vx/i);
}

if(at<430 && au<430 && av<430 && aw<430 && ax<430 && ay<430 && az<430 )
{
vx=at*0.00489;
i=(4.5-vx-0.55)/220;
rx=(vx/i);
}
lcd.setCursor(0,0);

if(vx>4.8)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("----INFINITY----");
}
else
{
if(rx<1000)
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(rx);
lcd.setCursor(7,0);
lcd.print((char)244);
}
else
{
lcd.clear();
rx=rx/1000;
lcd.setCursor(0,0);
lcd.print(rx);
lcd.setCursor(6,0);
lcd.print("k");
lcd.print((char)244);
}
}
lcd.setCursor(0,1);
lcd.print("Arduino Ohmmeter");
}

 

Author

15 Comments

  1. Peter (Gernany)

    Very good documentated. Program runs right on the first try on my ARDUINO MEGA 2560
    The auto-range is a very usefuk function and offers feasable R values from 10R to 100k.
    Trying out is highly recommended.

  2. D. Gudmundson

    Unfortuanately all the code did not get pasted. Here it is:

    int at, au, av, aw, ax, ay, az, a;
    double vx, i;
    float rx;

    void setup()
    {
    Serial.begin(9600);

    pinMode(2,OUTPUT);digitalWrite(2,LOW);
    pinMode(3,OUTPUT);digitalWrite(3,LOW);
    pinMode(4,OUTPUT);digitalWrite(4,LOW);
    pinMode(5,OUTPUT);digitalWrite(5,LOW);
    pinMode(6,OUTPUT);digitalWrite(6,LOW);
    pinMode(7,OUTPUT);digitalWrite(7,LOW);
    pinMode(8,OUTPUT);digitalWrite(8,LOW);
    }

    void loop()
    {
    for(int lp=2;lp=450)
    {
    vx=az*0.00489;
    i=(5-vx-0.55)/22000;
    rx=(vx/i);
    }
    if(ay>=450 && az=448 && ay<448 && az=439 && ax<439 && ay<439 && az=439 && aw<439 && ax<439 && ay<439 && az=430 && av<430 && aw<430 && ax<430 && ay<430 && az=430 && au<430 && av<430 && aw<430 && ax<430 && ay<430 && az<430 )
    {
    vx=at*0.00489;
    i=(4.5-vx-0.55)/220;
    rx=(vx/i);
    }

    if(at<430 && au<430 && av<430 && aw<430 && ax<430 && ay<430 && az4.8)?Serial.println(“INF”):Serial.println(rx); //sends only raw resistance data
    }

    • Mohit kumar

      i have done this project with the program which you mentioned in the site but it cant able to measure the 1k resistance should i have to totally change the code which is mentioned in the comments or else i have to add the code which is mentioned in comments along with the code which is mentioned in website. expecting a faster reply thanq.

  3. D. Gudmundson

    In case anyone is interested. I have rewritten this code so it is more streamlined and it uses Serial output instead of the LCD display. I love this project. I will be using it in a couple systems I am making at work to test whether pogo pins are touching a board in the correct place. Much cheaper than the alternative. This code also only send raw resistance data without the “K”. I an doing this because I am interfacing with a C# project I am developing. I hope someone is helped by it. Here is the code. From 210 line down to 98.

    int at, au, av, aw, ax, ay, az, a;
    double vx, i;
    float rx;

    void setup()
    {
    Serial.begin(9600);

    pinMode(2,OUTPUT);digitalWrite(2,LOW);
    pinMode(3,OUTPUT);digitalWrite(3,LOW);
    pinMode(4,OUTPUT);digitalWrite(4,LOW);
    pinMode(5,OUTPUT);digitalWrite(5,LOW);
    pinMode(6,OUTPUT);digitalWrite(6,LOW);
    pinMode(7,OUTPUT);digitalWrite(7,LOW);
    pinMode(8,OUTPUT);digitalWrite(8,LOW);
    }

    void loop()
    {
    for(int lp=2;lp=450)
    {
    vx=az*0.00489;
    i=(5-vx-0.55)/22000;
    rx=(vx/i);
    }
    if(ay>=450 && az=448 && ay<448 && az=439 && ax<439 && ay<439 && az=439 && aw<439 && ax<439 && ay<439 && az=430 && av<430 && aw<430 && ax<430 && ay<430 && az=430 && au<430 && av<430 && aw<430 && ax<430 && ay<430 && az<430 )
    {
    vx=at*0.00489;
    i=(4.5-vx-0.55)/220;
    rx=(vx/i);
    }

    if(at<430 && au<430 && av<430 && aw<430 && ax<430 && ay<430 && az4.8)?Serial.println(“INF”):Serial.println(rx); //sends only raw resistance data
    }

  4. The schematic is missing the wire from the cathode’s of the diodes to A5 (pin 28).

    • praveen

      yes that was a mistake. i have corrected the circuit diagram.

      regards
      admin

  5. Etienne Hamelin

    Your diodes will likely have a bias voltage varying slightly with current flow (i.e. with measured resistance), and with temperature, and even maybe different values between several diodes (even within same brand), this would limit the achievable precision.
    Why not remove those diodes, and put “unused” pins in hi-Z state (= input mode) instead?
    Your datasheet should give you an estimation of the minimal pin impedence in hi-Z state, so that you can compute how much current can leak through hi-Z pins (I suspect very little when you measure @ Vcc/2).

  6. Hi,

    I think there is vin (A5) missing in the circuit diagram.

    Best,
    Andreas

  7. I need to measure resistance from 0.05 ohm and 10 ohm, is it possible change the 220 ohm resistance with a 2,2 ohm resistance without breaking the micro?

    • Husmen Ketum

      Maximum current for digital output pins is 40 mA. That way 5V/0.04A=125 Ohm is absolute minimum. Regards.

  8. Eric Raymond

    thankyou the information is right and helpfull