Reading a voltage across resistance to measure constant current - Please advise!

I am finding that analog input pins on my Mega 2560 do not behave as I expect. T
To read the current signals from two constant current sensors (oxygen Electrodes) at intervals, I am reading the voltage across a resistance for each one. They operate on 24V and provide a fixed current in the range of 5-20 mA to indicate the oxygen level.

I have used the book "Arduino circuits and projects guide" by Gunter Spanner to set up a voltage divider, so that I have a 550 Ohm resistor in parallel with the divider (R1 = 100 and R2 = 380 Ohms) between the signal input terminal and ground. For protection, I also have a Schottky diode parallel to R1 between the ground and the line to the Analog pin; and another from this pin to 5V. I am referencing the analog pins to the 1.1V reference voltage.
As these are nominal resistance values, I have measured each one before connection, so as to calculate the total resistance for the Voltage drop and the voltage divider ratio. The calculated total resistance is 250 and the measured total (between the sensor input terminals) is 258.

My code for one sensor is attached below. For both sensors I get a current that does not match the current I measure with a meter before connecting the sensors. The two sensors meter measurements are similar, yet the Arduino values also differ for the two sensors. The Arduino values are fairly constant over time. Further, when the sensors are disconnected, I still get a (smaller) reading from the analog pins!
Can you advise what is happening here, and how I can correct it?
Thank you in advance! Rob

// Measuring two constant current sensors at intervals
unsigned long nowTime;
unsigned long prevTime; //time of last recording
const unsigned long oneMin = 60000;
int nowSecs = 0;
int printNo;
//constant current sensor definitions
const float voltDividera = 98.8/(98.8 + 377);
const float vRef =1.10;
const int analogPina = A10;
int readingA = 0;
const float calA = vRef/1023 * 0.94/voltDividera;
float voltageSa = 0;
float currenta_mA = 0;
void setup() {
    //Dissolved oxygen sensor code
    Serial.println("Measuring current from sensors with resistors");
    analogReference(INTERNAL1V1);
    prevTime = 0;
    printNo = 1;
    Serial.println("Data: printno, secs from start, ReadingA, VoltageA, CurrentA, ");
}
void loop() {
  nowTime = millis(); 
  if (nowTime - prevTime >= oneMin) { //set time when sensors recoreded
    prevTime = nowTime;
    nowSecs = int(nowTime / 1000);
    readingA = analogRead(analogPina);
    delay(5);
    voltageSa = readingA * calA;
    currenta_mA = (1000 * voltageSa / 258);
    Serial.print(printNo); Serial.print(", "); Serial.print(nowSecs); Serial.print(", ");    
    Serial.print(readingA); Serial.print(", "); 
    Serial.print(voltageSa); Serial.print(", "); Serial.println(currenta_mA); 
    readingA = 0;
    printNo++;
  }        
}

a fixed current in the range of 5-20 mA to indicate the oxygen level.

It is not fixed because it changes.
This is known as a current loop interface and is normally 4-20mA.

Why are you adding a diode that will make any reading none linear.

Please post a schematic of your circuit with real component values and part numbers on them. Hand drawn is preferable. Fritzing in not acceptable.

When using float variables all your constants must be float types as well, so

currenta_mA = (1000 * voltageSa / 258);

Should be

currenta_mA = (1000.0 * voltageSa / 258.0);

The calculated total resistance is 250 and the measured total (between the sensor input terminals) is 258.

Did you measure this disconnected from the Arduino? Otherwise a meter resistance measurement with an Arduino connected powered or not is meaningless.

Thank you Mike! fast reply.
Yes I did measure the total resistance with the soldered set of resistors etc disconnected from the Arduino.
Thanks for the point about making the numbers floating.

Apologies, by constant I meant that the sensor outputs a constant current (at each level of oxygen), irrespective of resistance between the signal wire and ground (I imagine within reasonable limits). I do not understand how this is done, but the sensor is an Oxyguard Model 420 2-wire Dissolved oxygen probe. The manual recommends a 250 ohm resistance between the signal wire (+) and -ve of the current recorder.

I have attached a schematic of the circuit with the (separately( measured resistances. I don't have part numbers but these are 1W resistors etc. this is a .jpeg - I have just googled Fritzing to see what you meant.
It sounds from your comment that I should remove the diodes?
Rob

RDabs voltage divider.JPG

The diodes will have no effect unless the voltages go above or below VCC. They are there for input protection for the Arduino.

I'm still a bit confused and don't have time to read the whole post again, but it looks like your voltage divider resistors are far too small. I would use something in the 10k to 100K range, but same ratio. That's the values for R1 and R2. Simply multiply each by about 100 to get values that will not load down the circuit.

Where's the vendor link for the datasheet for the sensor ?

I don't think you are supposed to add a voltage divider. All constant current circuits of the 4-20mA variety have 250 ohm resistor (sometimes added by user). There are two terminals , the output and GND. The
resistor is in series with the output before the terminal (or after). The constant current is the loop between the two terminals. Adding a voltage divider messes everything up.
Post the datasheet or a link to vendor you bought it from. Your setup sounds totally bogus. We need to verify your setup using the datasheet , which you have yet to post.

Raschemmel, if 20 ma flows through the 526 ohm resistor it will have 10.5 volts across it. That's double what the Arduino input can handle, so it makes sense that you would need a voltage divider. However the values used in that voltage divider will divert too much of the current flow, so they need to be scaled up.

Using this voltage divider calculator :Voltage Divider Calculator

I calculate 100K over 89K for R1 and R2

Yes but why not just use a resistor that gives you 5V at 20mA?
Then there is no need for a voltage divider and you can throw those diodes away.

The diodes are there for voltage protection on the input get the resistor right and you don’t need them.

Raschemmel, if 20 ma flows through the 526 ohm resistor it will have 10.5 volts across it.

You can't use a voltage divider across a current loop resistor for obvious reasons.

Reducing 10.5V to 5V WITHOUT loading the resistor is done using an OP AMP.

It's called a Voltage Subtractor. (you can't use a Non-inverting output because the output is always greater than one and you need VOUT/VIN =5V/10.5V= 0.4762 which is >1.
Therefore you have to use a Differential Amplifier as a SUBTRACTOR.

The op amp inputs have an input impedance around 100 Mohms so they won't load the resistor and change
the reading.

Yes but why not just use a resistor that gives you 5V at 20mA?

And then there's that ....

(525 ohm , FYI)

Grumpy_Mike:
Yes but why not just use a resistor that gives you 5V at 20mA?
Then there is no need for a voltage divider and you can throw those diodes away.

The diodes are there for voltage protection on the input get the resistor right and you don’t need them.

I don't know if that resistor can be changed, because we are not sure what exactly he his connecting to. It may require 562 ohms. I assumed that it needed to be that.

There is no need to add an op-amp to this circuit. A high impedance voltage divider will do the trick. It will draw some additional current, but scaled properly it is negligible.

The diodes are optional. It depends on how certain that you are that over voltage situations will not occur. Using a high impedance voltage divider such as the 100k over 89K will provide enough current limiting so that the Arduino diodes will not be abused.

I see a total R of 249.8 Ohms for the parallel branches, 9.5mA for the R3 branch and 10.5 for the R1, R2 branch and 10.5mA * 98.8 Ohms = 1.0374V for R1, but you still need a 27k in series with analog in pin to protect from 24V in event divider net fails, also a 10 nF ceramic cap from in pin to GND for noise bypass.
A 51R in parallel with 2.7k would give you 50.054 Ohms * 20mA = 1.001V.

Why are you using such low values for the voltage divider ? (all those resistors should be >50k)

Pick some higher values

Robbie, 20mA thru 50k would be 1000V!

How does the voltage across R1 compare to Serial prints? You should see 1mA per 50mV across R1.

Robbie, 20mA thru 50k would be 1000V!

Read my post. Do you see anything in my post about a constant-current (limiting) resistor ?
Look at your post:
RDabs voltage divider.JPG
Is that not a voltage divider (with resistors much too small) across the current limiting resistor ?

Why are you using such low values for the voltage divider ? (all those resistors should be >50k)

R3 is the constant current resistor:

MATLAB

10.5/526

ans =

0.0200

Is that not 20mA ?

Therefore, R1 & R2 were added by YOU and are not part of the sensor.
The values you chose for that voltage divider are what are messing up you reading.
REMOVE that voltage divider and put your current meter across the sensor and you will read 20mA.

Change the voltage divider resisors to >50k and you will see little change in the current.
You can even double that and go >100k

ALSO, your component designators are wrong.

R1 should be R2 and vice versa , as shown here

Change R2 (the resistor that connects to GND) to 90909.091 (91k) and change R1 to 100k.

The current through the voltage divider will then be 55uA

MATLAB
10.5/(191000)

ans =

5.4974e-05(A) = 0.000054974A => 55uA

ans*1000

ans =

0.0550

The current through the voltage divider with YOUR values is 22.1 mA.

0.0221A/5.4974e-05 = 402 times larger

Your bleeder current through your voltage divider is >the 20mA of your current loop.
Can't you see now why the value you read is double what it should be ?

RDabs voltage divider.JPG

Not a current limiting resistor, current sensing resistor, to read 20mA current loop. R3 is shunting the R1, R2 branch

Not a current limiting resistor, current sensing resistor,

It is a current limiting resistor. How else can the current be constant ?

It is not a current sense resistor.
A current sense resistor is a VERY small value:

current sense resistor

What does that say on the datasheet ? (it says "current sense resistor")

Are R1 and R2 part of the sensor or did you add those ?

They operate on 24V and provide a fixed current in the range of 5-20 mA to indicate the oxygen level.

That means that the resistor value should be
MATLAB

24/0.02

ans =

1200

Instead of 1200 ohms , you currently have:
Matlab

(526*(377+98.8)/(526+377+98.8))

ans =

249.8211

or you can do:

1/526+1/(377+98.8)

ans =

0.0040

1/ans

ans =

249.8211

Any way you cut the cake, you have 249 ohms instead of 1200.

I have no idea what your doing here :

I am referencing the analog pins to the 1.1V reference voltage.
As these are nominal resistance values, I have measured each one before connection, so as to calculate the total resistance for the Voltage drop and the voltage divider ratio. The calculated total resistance is 250 and the measured total (between the sensor input terminals) is 258.

I have measured each WHAT ? (analog pin ?)

In order to use the InternalAnalogReference , your analog input voltage must be <1.1V.

analogReference()
Description
Configures the reference voltage used for analog input (i.e. the value used as the top of the input range). The options are:

Where is the schematic for the circuit that reduces the voltage you are talking about to <1.1Vdc ?

In order to fix your problem you need to do the following:

  1. Change your code to use analogReference(DEFAULT)
  2. Change your R3 resistor to 1200 ohms (instead of 526)
  3. Change your R1 resistor (the one that connects to GND) to 91k.
  4. Change your R2 resistor to 100k.

Read the voltage as a range of 0 to 5V .

Where is the vendor link for your sensor ?
Why didn't you post that or the datasheet ?

Look at this 4-20mA current loop schematic and explain to me why the resistor shouldn't be 1200 ohms

  1. The Receiver Resistor
    It is much easier to measure a voltage than it is to measure a current. Therefore, many current
    loop circuits (such as the circuit in Figure 1) use a Receiver Resistor (Rreceiver) to convert the
    current into a voltage. In Figure 1, Rreceiver is a 250Ω precision resistor. The current flowing
    through it produces a voltage that is easily measured by an analog input of a controller. For the
    250Ω resistor, the voltage will be 1 VDC at 4 mA of loop current and 5 VDC at 20 mA of loop
    current. The most common Receiver Resistor in a 4-20 mA loop is 250Ω; however, depending
    upon application, resistances of 100Ω to 750Ω may be used.

if it runs off 24V and NOT 5V ?

(frankly , I don't think the output of the sensor is supposed to be >5V.
Most 4-20mA current loops have a 5V circuit. I think there is something you are not showing us
about the sensor that explains everything we need to know. (namely, is it or is it not a 24V circuit ?)

amdkt7:
I don't know if that resistor can be changed, because we are not sure what exactly he his connecting to. It may require 562 ohms.

No what ever makes you think that? The whole point about a current loop interface is that you can even short it out and only get 20mA max flowing. And what ever resistor you use will get 20mA up to a push voltage of 24V. So you are quite safe using a resistor that gives 5V at 20mA.

Rdabs stated that he wants to use the ADC with
Vref = 1.1 V! The sensor is good with 250 Ohms
as a load. So he included a voltage divider!
I think it was clever to use low value R values
to bring the total load to 250 Ohms!!
Herb

I think it was clever to use low value R values

Well I don’t. I think he just didn’t understand the situation.
It would have been much simpler to just use the potential divider alone without any other load resistor.

So you are quite safe using a resistor that gives 5V at 20mA.

Isn't that the problem ?
He DOESN'T have 5V . He has 10.5V. The voltage divider he added didn't lower the voltage across the 526 ohm resistor to 5V. It lowered it to 10.5V.

If he removes the voltage divider he added, the resistor value he should use is :

10.5/526

ans =

0.0200

5*526/10.5

ans =

250.4762

The current loop resistor should be 250 ohms.

He wouldn't need to add a voltage divider then because the voltage would be 5V.
He shouldn't try to use internal reference until he gets it working with the DEFAULT reference.

Adding that voltage divider dropped the total parallel resistance to 249.8211 ohms (close to the
correct value of 250) but half the current is NOT going through the current loop causing the reading
to be off by 100%.

ALL (or at least 99.9%) of the current should be going through the loop.
If he replaced the resistor with 250 ohms and used the values I recommended the current through the
voltage divider would be about 50uA , NOT 22mA !