Calculating Unknown Resistor with Arduino

Hello,

I'm attempting to calculate the resistance of unknown resistors using an Arduino Mega with simple voltage divider circuits. However, my readings are off by over an ohm and I can't figure out why. I posted about this project a few months ago: Analog Input Reads Incorrect Voltages - Using Arduino / General Electronics - Arduino Forum and thanks to everyone there, I was able to correctly measure the voltage using the Arduino. Coming back to this project again, I have hit another brick wall that I'm having a tough time breaking through.

Here is what my circuit looks like:

image

Note: the 5V rail is actually 5.15 volts (see below in code)
All grounds are common and connections are secured. The known 10 ohm resistors are mil-spec and have a tolerance of +/- 1% which is confirmed by a calibrated fluke meter.

Here is what the Arduino is reporting as an example (ohms; from A0 - A15):
5.97, 6.33, 6.10, 5.90, 5.93, 5.96, 5.96, 6.04, 6.22, 6.23, 6.11, 6.14, 6.11, 6.10, 6.37, 6.78

These resistances should be anywhere from 6.9-7.3 ohms as reported by the fluke.

Voltage wise, the Arduino and fluke are within +/- 0.1 volts, which, to me, rules out any wiring or power issues, but is instead a problem with my equation (ohms law).

Here is my code:

    // voltage/ohms settings
    const float _stepsInRange = 1024.0;
    const float _inputVoltage = 5.0;
    const float _knownResistance = 10.0;
    const float _powerSupplyVoltage = 5.15;

    // input pins
    const unsigned int _pins[16] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15};

    // read analog
    Serial.println("Reading analog inputs");
    for (int i=0; i < sizeof(_pins) / sizeof(unsigned int); i++) {
      int pin = _pins[i];

      // read raw input voltage
      analogRead(pin);  // Dummy reading - to set the MUX to `pin` and allow input to settle.
      delay(10);

      // average a multiple of reads to filter noise
      float sum = 0.0;
      for (int n=0; n < 100; n++) {
        // sum with correction according to http://www.skillbank.co.uk/arduino/readanalogvolts.ino
        sum += ((float)analogRead(pin) + 0.5) / _stepsInRange * _inputVoltage;
      }
      sum /= 100.0;

      // convert to a resistance
      // Calculation change taken from: https://physics.stackexchange.com/questions/285528/how-would-i-find-the-value-of-an-unknown-resistor-if-i-only-could-use-a-voltmete
      float knownVoltageDrop = _powerSupplyVoltage - sum;
      float knownCurrent = knownVoltageDrop / _knownResistance;
      float calulcatedResistance = sum / knownCurrent;
      Serial.println(calulcatedResistance);
    }

Any help is appreciated. Like I said, I don't think this is a wiring issue because I am getting really accurate voltage readings from the Arduino. It's when I convert it to a resistance does it go to left field.

Thank you for your time.
Jules

Why sum integer values into a floating point variable?

How do you mean? I am casting analogRead(pin) to a float, and then using floats for the rest of the line. Everything in that line is a float.

Switching to the below instead shows no difference.

      float sum = 0.0;
      for (int n=0; n < 100; n++) {
        sum += analogRead(pin) + 0.5;
      }
      sum /= 100.0;
      sum = sum / _stepsInRange * _powerSupplyVoltage;
      uint32_t sum = 0;
      for (int n=0; n < 100; n++) {
        sum += analogRead(pin);
      }

etc.

Little to no change.

Updated equation:

      uint32_t sum = 0;
      for (int n=0; n < 100; n++) {
        sum += analogRead(pin);
      }
      sum /= 100;

      float voltage = sum / _stepsInRange * _inputVoltage;
      float knownVoltageDrop = _powerSupplyVoltage - voltage;
      float knownCurrent = knownVoltageDrop / _knownResistance;
      float calulcatedResistance = voltage / knownCurrent;
      Serial.println(voltage);

Output:
5.97, 6.35, 6.12, 5.90, 5.92, 5.97, 5.95, 6.05, 6.22, 6.20, 6.12, 6.15, 6.10, 6.10, 6.38, 6.92

What are the resistors?
They are probably at room temperature when measured by Fluke but hot while in-circuit.
How do you measure the voltage drop over resistors? At leads of the resistor or at Arduino?

Isn't sum a reserved word?

No.

I assume you're referring to the known resistors? Mil-spec resistors with +/- 1% tolerance. If you mean the unknowns, I am substituting the actual component I'm measuring with resistors here for simplicity. They act as a resistor basically.

Either way, the circuit is only active for, at most, 5 seconds with anywhere from 30 seconds to 1 minute intervals, so they rarely get warm, let a lone hot lol.

As for voltage drop measurement, I just measured at both:
Arduino: 1.923 volts (A0 to GND in parallel) -- the Arduino is reporting very close to this
Known resistor leads: 2.67 volts

OMG. What are the unknown resistors???
You must also measure voltage on their leads to rule out wiring problems (Google Kelvin connection).

I'm still learning but I'd take a slightly different approach.


I think this gives a resolution of R1 / 1024 (ADC resolution) or 0.0098 Ohms.
You can keep all the inputs as ints and cast the entire expression to a double in a single line to mitigate drift and reduce processor clocks necessary.

Again, I have no idea which resistors you are talking about, or what you mean by "what are they" (i.e. what ARE they or what is their resistance?).

The unknowns are printed circuit heaters for snow plow headlights. They are literally resistors. Their nominal range of resistance is 6.5 - 7.5 ohms.

The known resistors are mil-spec 10 ohm resistors with a tolerance of +/- 1%.

Also, I measured at both the leads and arduino. Did you see any issues with there being a discrepancy?

I think it would help if you added Resistor numbers to your original diagram.

I don't see why you change the analog reading to a float. I would leave Vrail and Vi as uints until you had to divide them. After all they form a ratio they could be any two voltages with the same ratio.

Use the below equation (same as er_name_not_found) but do not use the 1.1 reference. The reason is; in the below equation, the only Reference item is R1. The voltages cancel out and become a ratio.

VarduioIN * R1/ (Vrail - VardunoIN) = R2

My original diagram already contains resistor values? Even though I state the nominal range of the unknowns is anywhere from 6.5 - 7.5 ohms, that is not guaranteed. They could possibly range anywhere from no connection to 100+ ohms and beyond. The parts I am using to build this circuit out are already known to be 6.9 - 7.3 with a fluke--hopefully that clears any confusion.

Also, I just tried your equation and haven't seen any improvement (hovering in the low 6 ohms). Maybe the voltage I am getting at the Arduino (~1.92 volts) is too low. I tried to plug in my variables with 7.3 as the expected R2 into a voltage divider calculator and it is showing that I have too low of a voltage.. I should be getting 2.17 volts, not 1.92.

Where are your grounds connected? Quick sketch.

Measure A0 in at the board with your FLuke.

A0 with the fluke is reading 1.88 volts. My tolerance goal is +/- 0.5 ohms if possible. Its not critical that they be exact, but the less noise there is, the more accurate my results will be :slight_smile:

External PSU1 is 5.15V @ 10A.

How are you powering the Arduino? are the grounds connected?

Sounds familiar! As owner of the electronic assembly company, they let me stuff 4 wirewound resistors into each circuit board to make heater boards for green lasers. They were used in snow plows so the operator could see where the end of the wing was. People figured I could do little damage with resistors!
Paul