Notifications
Clear all

Arduino resistor testing

Page 1 / 4

jeffreyjene
(@jeffreyjene)
Eminent Member
Joined: 2 years ago
Posts: 41
Topic starter  

I'm working on a piece for a instrument panel that finds the value of a resistor you plug into the board. My setup is an Arduino Uno with a 2K resistor that will be used to find the other in the divider (I'm aware of small inaccuracies and issues that happen if the resistors are not close to the same value). So 5V input with a 2K resistor and analog A0 at the meeting point of the two resistors, ground on one end and 5V on the other end of the divider (it actually comes out to about 5.04 on my meter). The "unknown" resistor is 1K. I get correct output voltage on my check, about 1.65 to 1.68 or so. The calculated value of the unknown resistor, however, is always off by 10-20 ohms for some reason (some resistors seem to be measured more accurately than others). I'm looking for a way to improve this. I've found code out on the web that seems to just return garbage for me so I kind of went with the basics:

floar vin = 5; //ish
float R1 = 2000.0; //my 2K known resistor
int  v = analogRead(refPin); //the reading for A0
float  buffer = v * vin; //calculating output voltage
float  vout = (buffer)/1024.0;
float  R2 = (vout*R1)/(vin-vout); //the formula

The value that comes out is 976 to about 981. I'm thinking that having a better vref would probably help out. I'm not even sure if what I'm trying to do will ever be as accurate as I want. Any suggestions?


Quote
Will
 Will
(@will)
Noble Member
Joined: 7 months ago
Posts: 1084
 

@jeffreyjene

If you're not using 1% resistors, maybe try to use a precision voltage reference like TL431 for vref ?

GreatScott has a video about them ...


ReplyQuote
DaveE
(@davee)
Estimable Member
Joined: 8 months ago
Posts: 226
 

Hi @jeffreyjene,

  I may be making an error as I haven't checked this out, but I don't think your basic approach is affected by the precise value of the "vref" voltage . However, that remark assumes the 5V supply (and 0V return) to your resistors is the same as that to your ADC reference levels. 

.... In more detail:

A quick look at the schematic for the Uno http://arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf shows the AVCC pin is connected to the 5V supply. (From a noise viewpoint, it maybe unfortunate the logic and analogue supplies to the chip are commoned to the same 5V supply, but that is a characteristic of the UNO design. Hopefully, this will not affect you.)

I am assuming that:

  • you are measuring the voltage at the junction of two resistors .. say R2 (unknown) and R1 (2 kOhm).
  • The voltage value read by the ADC (v) is in the range 0..1023  (its a 10-bit ADC) - this is the voltage across R1
  • The other (i.e. the end not connected to R1) end of R2 is connected to the (5V nominal) reference voltage of the micro ADC.
  • The other (i.e. the end not connected to R2) end of R1 is connected to ADC 0V reference
  • Your UNO ADC is configured in software to use AVCC (connected to 5V nominal supply) as its reference.

I think the above would be the case if you take the 5V and 0V connections to the resistors from the UNO board. Note, using a separate 5V supply for your resistors is not 'permitted' for this approach and analysis.

Then:

  • By definition, if you could use the ADC to measure the voltage at the '5V' end of R2, the reading would be '1024' -- and that corresponds to the voltage across R1 + R2
  • 'v' (a number in the range 0..1023) is the voltage measured by the ADC at the junction of the resistors, which corresponds to the voltage across R1
  • then as it is a voltage divider, the voltages are proportional to the resistance values, so
    •    v / 1024 = R1 /(R1 + R2)

So a little maths rearrangement shows:

v * (R1 + R2) = 1024 * R1

 

v * R2      =  R1 *  (1024 - v)

 

R2   =  R1 * ((1024 - v) / v)      where R1 = 2000 for a 2kOhm resistor

Note there is no mention 5V as it is a ratiometric measurement. The value of the vref is irrelevant.

............

Of course this simple analysis has not explored the effects of tolerances of components, errors in ADC measurements such as non linearity, and so on which will also affect the accuracy of the measurement. 

Also, for measuring higher resistor values than a few kOhms, beware of the ADC input drawing a current when it samples, thereby changing the voltage it measures. This will be affected by the sampling time ... careful reading of the data sheet is required.

--------------

Having done the analysis with the unknown resistor connected to the 5V reference supply, it occurs to me that if this point is accidentally connected to ground, then it will obviously depower the UNO. There could be an argument for swapping the known and unknown resistors if this is a concern. This will slightly alter the maths, but the principle will be unchanged.

-------------

I hope this is of interest. Dave


ReplyQuote
jeffreyjene
(@jeffreyjene)
Eminent Member
Joined: 2 years ago
Posts: 41
Topic starter  

@davee Thanks much. I've stripped this down as far as I can to show what is actually happening. I'm trying to measure the value of an "unknown" resistor using a simple voltage divider setup and an Arduino Uno. I have a 1000K resistor with a 33ohm resistor (the "unknown" value) with a wire to D12 at the end. A0 is connected to the junction and another wire going from D2 to the end of the 33ohm. I'm setting D12 to OUTPUT HIGH and D2 to LOW. It gives me an output of about 52 which is very inaccurate (I've calibrated by measuring the VIN which is in this case is 5V). If I reverse the setup with D12 at LOW and D2 at HIGH (as I saw in a recent tutorial on how to do this) the value is a crazy 18301! However, if I connect ground in place of the D2 wire it reads quite accurately at 31.1. Trouble is I want to reuse that breadboard "line" for another function. My plan was to turn D2 "on and off" by setting it to OUTPUT HIGH (on) or INPUT (off). This approach seems to work in other projects I've seen, but for some reason not here. Obviously ground and another D pin cannot go to the same row. Does anyone know why this setup isn't working? I've supplied the setup and code.

Code:

//resistor meter
int resistorPin = A0;
float R1 = 0;
float R2 = 0;
int v = 0;
float vin = 5;
float vout = 0;
float buffer = 0;

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

void loop(){

   //1000
  R1 = 1000;
  pinMode(12, OUTPUT);
  digitalWrite(12, LOW);
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);
  
  v = analogRead(resistorPin);
  buffer = v * vin;
  vout = (buffer)/1023;
  R2 = (vout*R1)/(vin-vout);      
  
  Serial.println(R2);

  delay(100);
}
OhmMeter1

ReplyQuote
Will
 Will
(@will)
Noble Member
Joined: 7 months ago
Posts: 1084
 

@jeffreyjene 

Since your methodology always has D2 HIGH, why not just connect directly to 5V instead of D2 ? Then D2 will be perfectly available as needed.

 

PS - you should really move the pinMode commands to the setup() group and include A0 as INPUT.


ReplyQuote
jeffreyjene
(@jeffreyjene)
Eminent Member
Joined: 2 years ago
Posts: 41
Topic starter  

@will The D2 will not always be high. When something else is using that terminal D2 will be INPUT. That's the idea, at least. The pinModes are outside the setup() because they will change at runtime.


ReplyQuote
Will
 Will
(@will)
Noble Member
Joined: 7 months ago
Posts: 1084
 

@jeffreyjene 

Obviously you have plans which are not reflected in your sketch or Fritzing diagram.

What I'm pointing out is that as far as measuring the resistance is concerned, a direct connection to 5V is all that's required. Similarly, you could connect the other resistor to GND instead of D12.

What is the nature of the additional circuitry to be added after this ?


ReplyQuote
ronalex4203
(@ronalex4203)
Estimable Member
Joined: 1 year ago
Posts: 237
 

@jeffreyjene Your code does not reflect that. @will is right on the money with his suggestions. 


ReplyQuote
jeffreyjene
(@jeffreyjene)
Eminent Member
Joined: 2 years ago
Posts: 41
Topic starter  

@ronalex4203 As mentioned in the above post, the code has been stripped down here. Yes, there will be additional connections being made to this terminal, though the plans are not complete. At this point it is assumed that the above is true and the wires set the way they are for a reason. Incidentally, while the mentioned comments about how to attach the 5V and where to declare the pinModes are decent suggestions, the above is still valid code and it doesn't help the task at hand. The code and Fritzing above does NOT work on it's own, and that is what I'm trying to fix. Implementing the suggestions does not help.


ReplyQuote
ronalex4203
(@ronalex4203)
Estimable Member
Joined: 1 year ago
Posts: 237
 

@jeffreyjene Sorry, I don't understand any of that so can't help. Good luck.


ReplyQuote
jeffreyjene
(@jeffreyjene)
Eminent Member
Joined: 2 years ago
Posts: 41
Topic starter  
OhmMeter1

Here's an example. The D2 cannot be replaced with ground, as it will be used by another pin connected to that column later. Unless someone knows a way to connect a digital pin and a ground pin to the same column (I doubt that).


ReplyQuote
ronalex4203
(@ronalex4203)
Estimable Member
Joined: 1 year ago
Posts: 237
 

@jeffreyjene I believe @will said D2 to +5V but your point is taken. Obviously if D2 will have other connections and +5V would damage any of those other connections then don't do that. We were just commenting based on the supplied circuit and code. These exercises remind me of the blind man and an elephant.


ReplyQuote
Will
 Will
(@will)
Noble Member
Joined: 7 months ago
Posts: 1084
 

@jeffreyjene 

Why would you think that you could reverse the polarity and use the same calculation ?

As I understand it, declaring a pin as INPUT leaves it as floating, so it may not behave as you expect. I would expect that if you actually implemented the circuit shown in your post of today at 10:40 that you would not get any useful values for your calculation.


ReplyQuote
jeffreyjene
(@jeffreyjene)
Eminent Member
Joined: 2 years ago
Posts: 41
Topic starter  

@will Well, seeing as this has worked in countless other demonstrations I've seen, I assumed that setting pins to INPUT worked. I guess not. So unless I'm misunderstanding, what you are saying is that a terminal that is already wired to a pin cannot be used by another pin effectively. Funny thing, it does seem to work when I replace the D2 with ground. Then setting the front of the resistor pins (9, 10, 11, and 12 respectively) to INPUT when they are not being used DOES indeed work, so there must be something to the idea. I might not be able to do the same on both sides of the divider though. As for reversing polarity, I have no idea what you are talking about.


ReplyQuote
Will
 Will
(@will)
Noble Member
Joined: 7 months ago
Posts: 1084
 
 
 
Posted by: @jeffreyjene

I have a 1000K resistor with a 33ohm resistor (the "unknown" value) with a wire to D12 at the end. A0 is connected to the junction and another wire going from D2 to the end of the 33ohm. I'm setting D12 to OUTPUT HIGH and D2 to LOW. It gives me an output of about 52 which is very inaccurate (I've calibrated by measuring the VIN which is in this case is 5V). If I reverse the setup with D12 at LOW and D2 at HIGH (as I saw in a recent tutorial on how to do this) the value is a crazy 18301! However, if I connect ground in place of the D2 wire it reads quite accurately at 31.1.

First you set D12 HIGH and D2 LOW and then you reverse to D12 HIGH and D2 LOW.

That's what i revered to as "reversing polarity". First current flows one way and gives you a reading and then you reverse the direction of current flow and take another reading. Yet you use the same formula despite the fact that one of the readings is taken on the high voltage side and the other test is taken on the low voltage side.

I'm unable to understand why you think 31.1 is a close approximation to 330 ohms, but maybe that's just a typo.

Apparently I'm missing something very fundamental in your setup.

BTW: I'd suggest that you switch over to the much superior formula explained above by @davee.


ReplyQuote
Page 1 / 4