Calculating integers far greater than 65535.

mortifyu

New Member
Hi Guru's,

I have researched pretty hard trying to find the clever answer to my current query. I have semi found the answer, but can't find how I can implement my values.

The resolve appears to be cleverly written by the proven master of math around these parts, AllyCat (Alan) and can be viewed in the code of post #1 here in this thread. I altered the values denoted by Symbol NUMERATOR and Symbol DIVISOR and Alan's code did return the value I had hoped.

What I can't figure out is how to effectively get my values into a SYMBOL/S on the fly (if this is even possible) in order to process my required calculations a number of times.


With the best possible accuracy using PICAXE 10bit ADC, a 5.000 VDC reference, a 0.1% 510R ohm resistor for R2 and scaling up and down where necessary, I basically want to determine the unknown value of R1 in the attached circuit being any value between 0-310 ohms. Beyond 310 ohms will be deemed a fail.

23779

*****************************************
eg.
RawADC = 1022
Vin = 5
R2 = 510

Vout = RawADC*Vin/1023
= 1022*5/1023
= 4.99511241 VDC

R1 = (R2*Vin) / Vout - R2
= (510*5) / 4.99511241 - 510
= 0.49902198 OHMS
*****************************************

Code:
'08M2 PICAXE

Symbol RawADC = w0
Symbol Vin = w1
Symbol Vout = w2
Symbol R1 = w3
Symbol R2 = w4

Vin = 5
R2 = 510

readadc10 c.4, RawADC

Vout=RawADC*Vin/1023
R1=R2*Vin/Vout - R2

sertxd(#R1,cr,lf)

end

Or is there a better/simpler/smarter way?


Thanks in advance Guru's.



Regards,
Mort.
 

Buzby

Senior Member
Hi Mort,

There are a few thing you can do to get better results, before you get into multi-word maths.

The span of the ADC in the PICAXE is 0v to 5v, but your circuit only uses 40% of that span.
( When R1 is very low, Vout is near 5v. When R1 is about 300ohm, Vout is near 3v. There is only 2v difference between max and min. )

If you make R2 significantly smaller, say 51ohm, then the range is 0.7v to 5v.
( However, reducing R2 means more current, which may ( or may not ) be a problem for you. )


Another method, depending on which PICAXE you are using, is to set the bottom of the ADC range to a different value than 0v.
( See http://www.picaxe.com/BASIC-Commands/Advanced-PICAXE-Configuration/adcconfig/ )

If you set the lower end of the ADC range to, say, 3v, then the full 1024 bit ADC range now applies across 3v to 5v, not 0v to 5v.

Play with the numbers in Excel to see the differences.

Cheers,

Buzby
 

hippy

Technical Support
Staff member
Buzby beat me to it. Unless something is done to adjust how the ADC is converting, the readings from READADC10 won't be sufficiently different to be able to determine the R1 better than to +/- 1 ohm resolution. I recall you previously indicated you wanted to measure to 0.1 ohm accuracy.

I have to admit I am intrigued as to the 'why' ?
 

eclectic

Moderator
I have NO idea if it's useful, but

Dr Jeremy Leach was a prolific contributor on this site

and was involved in


e
 

AllyCat

Senior Member
Hi,

I think it's really just a matter of choosing suitable units or scale factors. For example, dividing microvolts by microamps will still give a value in Ohms. For tenths of an Ohm you'd multiply the numerator by 10 or reduce the divisor by a factor of 10, etc..

The DIVISOR is just a normal Word value so you can just read that (or calculate it) in the program as usual. The NUMERATOR is 32 bits but generally only the Higher word is significant (particularly if you only have a 10-bit ADC value). But you want the data values to nearly "fill" the variables to get good resolution (accuracy may be another matter). For example, if you have a value of 3000 (representing 3.000 volts) in a Word (W2), then you can scale that up into the double-word NUMERATOR by multiplying by 10,000 (to give units of tenths of a uV). That's easy with PICaxe Basic, the "High Word" is obtained by using the ** operator, e.g. W3 = W2 ** 10000 , and the "Low Word" with the normal * operator, i.e. W2 = W2 * 10000 . Put the Divisor (e.g. in uA) into W1 and run my code snippet. ;)

Cheers, Alan.
 

mortifyu

New Member
If you set the lower end of the ADC range to, say, 3v, then the full 1024 bit ADC range now applies across 3v to 5v, not 0v to 5v.
Hi,

Thanks for the info. It appears (if I am reading correctly), the minimum PICAXE I can use to gain the benefit of external VRef- is 18M2. The PICAXE I 'was' looking to use was 08M2, however this is not critical and I can step up to using a 18M2 instead. I presume this means I would need to have another voltage divider connected to pin C.2 of a 18M2 in order to give me the new zero reference point. Is this correct?


Unless something is done to adjust how the ADC is converting, the readings from READADC10 won't be sufficiently different to be able to determine the R1 better than to +/- 1 ohm resolution. I recall you previously indicated you wanted to measure to 0.1 ohm accuracy.
Yes, I too calculated an approximate current resolution of only +/- 1 ohm. Even over the full spectrum of 0-1024 I'd still only get about +/- 0.3 ohm resolution (310/1024). For this reason I am considering using an external 12bit (at least) ADC chip with I2C interface.

However I end up going about this, the large number math has thus far been the thorn in my side.


As to the 'why'... The fine details I'd prefer not to disclose on a public forum.


Regards,
Mort.
 

mortifyu

New Member
Hi,

I think it's really just a matter of choosing suitable units or scale factors. For example, dividing microvolts by microamps will still give a value in Ohms. For tenths of an Ohm you'd multiply the numerator by 10 or reduce the divisor by a factor of 10, etc..

The DIVISOR is just a normal Word value so you can just read that (or calculate it) in the program as usual. The NUMERATOR is 32 bits but generally only the Higher word is significant (particularly if you only have a 10-bit ADC value). But you want the data values to nearly "fill" the variables to get good resolution (accuracy may be another matter). For example, if you have a value of 3000 (representing 3.000 volts) in a Word (W2), then you can scale that up into the double-word NUMERATOR by multiplying by 10,000 (to give units of tenths of a uV). That's easy with PICaxe Basic, the "High Word" is obtained by using the ** operator, e.g. W3 = W2 ** 10000 , and the "Low Word" with the normal * operator, i.e. W2 = W2 * 10000 . Put the Divisor (e.g. in uA) into W1 and run my code snippet. ;)

Cheers, Alan.
Thanks mate, I'll have a further tinker with this.


Regards,
Mort.
 

AllyCat

Senior Member
Hi,

It depends if you (still) want a resolution of 0.1 ohm at the 310 ohms value. If you do, then that 0.03 % "accuracy" opens a real can of worms.

To improve the "percentage" resolution, you need a lower series resistor, but this would of course increase the current and power dissipation in the resistors. To resolve to 0.1 ohm with a 10 bit (1024 level) ADC needs a (maximum) series resistance of 100 ohms. MUST the resistor under test (R1) be on the positive side of the Reference resistor (R2) ? That makes the whole measurement much more difficult.

With the "unknown" resistor on the earthy side, the measurement becomes much easier; You can use the the FVR2048 reference for the ADC (or arguably the FVR1024) and remove any need to raise the Lower Reference voltage. If it's essential to use a fixed 5 volts rail, you can still lower the effective driving resistance (and voltage) by putting another resistor in parallel with R1. For me, Thevenin's theorem is probably the second most useful formula after Ohm's Law. ;)

Cheers, Alan.
 

hippy

Technical Support
Staff member
I'm with AllyCat; putting the resistor under test at the bottom and using FVR for Vref+ you should be able to get down to +/- 0.5 ohm.

It might be easier to determine the R from a lookup table rather than a reverse calculation, though that view might be because I'm struggling with the maths.

I am still of the view that charging up a capacitor and timing how long that takes may be a better way to increase resolution and accuracy.

Or having a DAC generate a voltage the voltage divider output can be compared against.
 

AllyCat

Senior Member
Hi,

Indeed, many of the low cost "Weather Stations" achieve almost 16-bits ADC resolution for temperature (thermistor) measurements by simply "counting" how long it takes the thermistor to charge a reference capacitor up to a threshold voltage (often Vcc / 2). Typically then repeated with a second, Reference, resistor so the stability of the (electrolytic) capacitor is irrelevant, it's just the ratio of two resistances / counts.

I'm struggling with the maths.
Hippy ??????

IMHO the ** operator is the only "magic" that's needed. It allows creation of a 32 bit value immediately before division (the only time that degree of resolution is required) and makes "calibration" or "trimming" of precise values very easy, e.g. to reduce a variable w1 by exactly 1% is w1 = w1 ** 64880 .

Cheers, Alan.
 

lbenson

Senior Member
to reduce a variable w1 by exactly 1% is w1 = w1 ** 64880
Interesting. Does that mean to reduce a variable w1 by +any+ percentage is:
Code:
percentage=100-11 ' e.g.11 percent reduction
w2=655*percentage ' losing .35
w1=w1 ** w2
(Perhaps code can be optimized.)
 
Last edited:

hippy

Technical Support
Staff member
I'm struggling with the maths.
Hippy ??????

IMHO the ** operator is the only "magic" that's needed.
Not the PICAXE math implementation per se; my brain's struggling with converting the mathematical -

Nadc * Vref = Vpsu * R1 * 1023 / ( R1 + R2 )

To -

R1 = ...


And not that it's particularly hard to do that, but whatever I do, I come up with something which doesn't give R1 as it should be in my test harness.

Updated : Perhaps because it should be -

Nadc * Vref = Vpsu * R2 * 1023 / ( R1 + R2 )

To -

R2 = ...

Finally : That was it -

R2 = ( Nadc * Vref * R1 ) / ( ( Vpsu * 1023 ) - ( Nadc * Vref ) )

and, when Vref = Vpsu -

R2 = ( Nadc * R1 ) / ( 1023 - Nadc )
 
Last edited:

AllyCat

Senior Member
Hi,

Yes, W2 is actually 655.36 * percentage which you can calculate on a pocket calculator (or now a phone) to the nearest bit (in 65536). The ** operator simply calculates W1 * W2 / 65536 (or you'd need to reduce that to 65535 to fit in a word calculation).

Originally I though this was only useful for scaling down values, but you can also increase them slightly (up to +99.998%) with (say) W1 = W1 ** 655 + W1 for a 1% increase. ;)

Cheers, Alan.
 

AllyCat

Senior Member
Hi,

With the Resistor Under Test "hanging down" from the supply rail you really need to make Vref = Vpsu to get a sensible measurement. That's why I've been so critical in the past of the PIC hardware used for the READINTERNALTEMP measurement. ;)

With the unknown resistor to ground it becomes a simple potential divider calculation, where you would first calculate the multiplier for the Reference ADC value given by Vpsu / Vref to give an equivalent "full scale" value. You can then calculate the (integer) values across the two resistors and the unknown resistance becomes Ndut / Nref * 510.

EDIT: To complete the design: To resolve a 0.1 ohm step at the low resistance end of the range with a 10 bit ADC needs a 100 ohm series resistance. Then, as the resistance is increased, the current must fall so the resistance steps will increase, i.e. R = Vstep / I . Of course, at 310 ohms (+100 ohms in series) it's not possible to resolve 1 part in 4100 with a 10-bit ADC (1024 steps). To retain smaller than 0.1 ohm steps over more of the range would need lower-valued reference resistors.

For the ADC to reach full-scale at 310 ohms (+100 ohms reference) with a FVR2048 reference voltage, needs a supply of 2.048 * 410 / 310 = 2.71 volts. That would give the lowest power dissipation and optimum use of the ADC range. This is where Thevenin comes into play: To give a little headroom, assume a 3 volt target (open circuit), which needs a resistor divider ratio of R : 1.5R from 5 volts. "Looking back" into the divider chain, Thevenin puts the two resistors in parallel, i.e. 0.6 R and we want that to be 100 ohms (source impedance). Therefore, the resistors should be nominally 167 (from 5v) and 250 ohms (across the unknown resistor), so use typically 160 + 240 ohms or 150 + 220 ohms. Maximum power dissipation in the 167 ohms would be V2 / R = 25 / 167 =150 mW (DUT = 0 ohms) and maximum power in the DUT (equal source and load impedances) = 1.5 * 1.5 / 100 = 2.25 / 100 = 22.5 mW.

Cheers, Alan.
 
Last edited:

mortifyu

New Member
Hi,

It depends if you (still) want a resolution of 0.1 ohm at the 310 ohms value. If you do, then that 0.03 % "accuracy" opens a real can of worms.

To improve the "percentage" resolution, you need a lower series resistor, but this would of course increase the current and power dissipation in the resistors. To resolve to 0.1 ohm with a 10 bit (1024 level) ADC needs a (maximum) series resistance of 100 ohms. MUST the resistor under test (R1) be on the positive side of the Reference resistor (R2) ? That makes the whole measurement much more difficult.

With the "unknown" resistor on the earthy side, the measurement becomes much easier; You can use the the FVR2048 reference for the ADC (or arguably the FVR1024) and remove any need to raise the Lower Reference voltage. If it's essential to use a fixed 5 volts rail, you can still lower the effective driving resistance (and voltage) by putting another resistor in parallel with R1. For me, Thevenin's theorem is probably the second most useful formula after Ohm's Law. ;)

Cheers, Alan.
Hi,

The responses (from ALL of you) are greatly appreciated and I am eternally grateful for the loan of your brain's. I am trying hard to understand and take it all in.

Resolution to at least 0.1 ohms with a hopeful accuracy of +/- 0.05 ohms is important here and this is why I am thinking I straight out just need higher a resolution ADC to at least 12bits. In any case the math will still be required. How I electrically and programmatically achieve this result is not particularly critical and I am completely flexible with the circuit.

The resistor under test can be on the earth side. In fact I did have it there initially. What made me change to having it on the 5V rail side was purely part of the math I couldn't achieve. Being: R1 * 1/(Vin/Vout - 1).

A further problematic issue I didn't mention earlier is that I need to set a failsafe current limit to an absolute MAX of 18mA under ANY condition, however the 5.000VDC reference is only capable of supplying 10mA anyway which obviously equates to a total load of 500 ohms minimum between 5V and GND.

23781

An absolute MAX current of 18mA is so important that I will be backing up the LM317 configuration with a second identical circuit in series. I know that sounds almost crazy and perhaps overkill, but in this case, it is more paramount than one may possibly imagine.

And before anyone says it... I know, I know... It may appear I am chasing rainbows and unicorns with this, but there is a real purpose to it all. 😄

Thevenin's theorem, come on mate... I'm not a rocket scientist like perhaps some of you guys. I have previously never heard of it. You remind me of one of my good friends that writes very complex ASM code. He is so intense with it all it's like English is his second language. :giggle:


Regarding my current topic of dilemma, I am eager to absorb and apply the necessary further knowledge with PICAXE to accurately and reliably achieve my goal of measuring resistances of 0-310 ohms at 0.1 ohm resolution with the hopeful accuracy of +/- .05 ohms.

So I can make good use of the ** operator now and in the future, could someone kindly write an example equation in super simple format so I can clearly get my head around what is actually occuring when using it?


Kind regards,
Mort.
 

AllyCat

Senior Member
Hi,

Achieving 0.1 ohm resolution (maybe even accuracy) when measuring a one ohm resistor is relatively easy. But getting 0.1 ohm resolution (let alone accuracy) of a 300 ohm resistor (in series with 500 ohms) will be difficult, even with a 12 bit ADC.

Thevenin really isn't very difficult and sometimes can be extremely useful (Google might find a more User-friendly description than Wikipedia). Basically you just replace any voltage sources (e.g. the power supply) with a short-circuit and remove the load (e.g. the DUT) to calculate the desired resistances and voltages. The most difficult part is calculating the value of resistances connected in parallel, but here an "estimate" or an on-line calculator may be sufficient. My "Edit" above obviously doesn't meet your revised specification, but may give an idea of what factors need to be considered.

The simplest use of the ** operator I can think of is, if you wanted to multiply 1000 by 1000 (e.g. stored in W1). You can calculate W2 = W1 * W1 which should give a (correct "Low" word) result of 16,960, because the word variable has overflowed the maximum value of 65535. However, if you calculate W3 = W1 ** W1 you should get a result of 15, which is the "High" word of the double-word result. To check; if you calculate the following on a pocket calculator (or phone) : 15 * 65,536 + 16,960 (i.e. W3 : W2) you should get exactly 1,000,000 . ;)

Cheers, Alan.
 

hippy

Technical Support
Staff member
An absolute MAX current of 18mA is so important that I will be backing up the LM317 configuration with a second identical circuit in series. I know that sounds almost crazy and perhaps overkill, but in this case, it is more paramount than one may possibly imagine.
I don't know exactly what you are doing but it sounds on par with measuring the resistance of a detonator coil inside a brick of C-4, something medical related, something with massive adverse consequences when it goes wrong.

Whatever it is, I'm being led to believe that the only advice I can give is that you are likely better off not doing it.

Given there's no way to perform a risk analysis it's not even clear that a PICAXE is suitable for the task so the recommendation would have to be that it is not.

The resistor under test can be on the earth side
No it cannot. What if the ADC pin becomes an output, through a glitch in the silicon, a bug in the firmware, a coding error ?
 

AllyCat

Senior Member
Hi,

I agree with hippy, but for rather different reasons:
the 5.000VDC reference is only capable of supplying 10mA anyway
The first way you ensure that a circuit is accurate and reliable (which you say are the absolute requirements) is to ensure that all components are operating well within their ratings. If a device is "only capable of supplying 10 mA" then it should be operated at 5 mA, or even 2 mA.
An absolute MAX current of 18mA is so important that I will be backing up the LM317 configuration with a second identical circuit in series.
Firstly, by putting any device (e.g. current limiter) in series with the voltage Reference, you appear to have largely eliminated it's function of being an accurate Reference voltage ! Also, the mantra for achieving high reliability is generally to KISS (Keep it SimpleS). Ensure that the "5 volts" can NEVER significantly exceed that voltage, for example by adding a "crowbar" circuit, in its simplest form a shunt regulator such as a zener diode. Many years ago I was told that the construction of zener diodes is such that they "always fail safe" (in the context of protecting against over-voltage) to a short circuit. I don't know if that's still true - anything containing bond wires can "fuse" to an open circuit (which would remove the shunt protection).

Having ensured that the supply voltage can never become excessive, a good quality resistor (adequately rated) will guarantee that the current can never significantly exceed that calculated by Ohms Law (unless there's an unexpected source of negative voltage). Of course anything you attach to the circuit must reach the same standards. So, as hippy indicated, the ADC also needs a "protected" supply voltage and a suitably high resistance in series with its input (but not so high that it degrades the accuracy).

Cheers, Alan.
 

mortifyu

New Member
The simplest use of the ** operator I can think of is, if you wanted to multiply 1000 by 1000 (e.g. stored in W1). You can calculate W2 = W1 * W1 which should give a (correct "Low" word) result of 16,960, because the word variable has overflowed the maximum value of 65535. However, if you calculate W3 = W1 ** W1 you should get a result of 15, which is the "High" word of the double-word result. To check; if you calculate the following on a pocket calculator (or phone) : 15 * 65,536 + 16,960 (i.e. W3 : W2) you should get exactly 1,000,000 .
Thank you for this. Doing the exercises you mentioned above clearly clarifies the operation. Hopefully I can now find my way to the final result.



I don't know exactly what you are doing but it sounds on par with measuring the resistance of a detonator coil inside a brick of C-4, something medical related, something with massive adverse consequences when it goes wrong.
None of the above. Bottom line is that in this case error/failure stands to potentially put me to substantial expense and this is why I personally oversee and orchestrate designs and operations myself thus placing the onus solely on me. With this critical and careful approach I have always achieved my goals flawlessly and in many past cases achieved the result where others said, "It can't be done." Some of my past device designs have exceeded 3000 individual components and remain in critical operation today with a demonstrated and proven track record of ZERO failures and/or errors exceeding 10 years. So I am confident and have the desire and mindset to just get things right upfront. These days many products are not made to last... And then there is MORT SPEC. ;)


No it cannot. What if the ADC pin becomes an output, through a glitch in the silicon, a bug in the firmware, a coding error ?
The ADC is undoubtedly a high impedance input, as such for example a 1K resistor could be placed between the ADC input and sense point with a negligible effect to the signal. Along with a protection zener 'crowbar' eliminates any of those concerns. Any adverse effect any implemented protection may have can always be software or otherwise compensated.



Firstly, by putting any device (e.g. current limiter) in series with the voltage Reference, you appear to have largely eliminated it's function of being an accurate Reference voltage !
This is true, however in this case is resolved by taking feedback from the output side of the current limiter in turn creating an offset to compensate any error.

EDIT: Here is a suitable voltage reference: https://au.rs-online.com/web/p/voltage-references/1659738/

...the construction of zener diodes is such that they "always fail safe" (in the context of protecting against over-voltage) to a short circuit.
This is also true and correct. For absolute surety, a couple 'crowbars' implemented in parallel will see the earth open up and swallow me whole before component failure poses any problem.



For the beneficial purpose of this supreme forum, once I have achieved the goal, I will post the circuit along with the PICAXE code allowing it to be repeatable by any interested parties.



Regards,
Mort.
 
Last edited:

hippy

Technical Support
Staff member
The ADC is undoubtedly a high impedance input
I recall the effective resistance of the ADC input is said to be about 36K. Put that in parallel with a 510R reference resistor and it will change that. If put across the resistor to test it will affect the circuit non-linearly.
 

mortifyu

New Member
I recall the effective resistance of the ADC input is said to be about 36K. Put that in parallel with a 510R reference resistor and it will change that. If put across the resistor to test it will affect the circuit non-linearly.
Thanks for the info mate. I am a little surprised for it to be that low. However I have decided in this case it will be best to find a suitable external ADC with greater resolution. I don't suppose you have any particular product suggestions 16-24bit?

P.S. Just out of curiosity, where in the world are you located Hippy?



Regards,
Mort.
 

AllyCat

Senior Member
Hi,

I believe 36 kohms is (approximately) the value of the PICaxe "Weak Pullups"; AFAIK the PICaxe ADC uses a capacitive-divider method (and of course CMOS technology) so the input impedance is basically "very high". BUT, because the input has a sample-and-hold stage, Microchip recommend that the SOURCE impedance should not exceed 10 kohms.
... find a suitable external ADC with greater resolution. I don't suppose you have any particular product suggestions 16-24bit?
Do you realise what you're asking for? If we assume that the input range is 5 volts (which is unusually large for a raw ADC), then a 16-bit ADC would have steps of 5000 / 65535 = 0.076 mV, and 24 bits would have a resolution of 0.3 uV (or 300 nanoVolts). To put that into perspective, IMHO in practice you may need to look at instrumentation grade Op-Amps and techniques (for buffering or to control your Reference offset control loop) to get a differential offset voltage of much better than 1 mV (equivalent to about 12 bits resolution). Yes, plenty of ADCs do have a "headline" figure of 24 bits, but you need to read the data sheet carefully to see what that actually means. And of course all this refers to resolution NOT "accuracy".

Cheers, Alan.
 

mortifyu

New Member
Do you realise what you're asking for?...
Yes, I certainly do.

Some research earlier this evening turned up this clever little device that maybe sufficient.


Not that I have finished looking around just yet, but the ADS1114 could be sufficiently suitable and offers (15bit resolution, not 16bit as it may appear at first glance) which equates to 32767 steps, 187.5uV/step if using the 6.144v FSR or 125uV/step with a 4.096v FSR. It also employs the convenience of I2C.

Another benefit I see is very high input impedance.


Regards,
Mort.
 
Last edited:

premelec

Senior Member
We don't know what your project is - consider noise, resistor noise and thermoelectric effects... good luck...
 

marks

Senior Member
Hi mortifyu,
here's some code to try for the cheap version you could use it at 3v and a precision resistor not really required just enter the value.
extra steps required lol
good luck with getting anything delivered all planes here are grounded and shipping likely to be difficult
sorry about the formatting never seems to work for me.
Rich (BB code):
#picaxe 08m2 
#terminal 4800

SYMBOL ADCvalue2 = W2 SYMBOL X2 = W2
SYMBOL inX2 = W3 SYMBOL D2 = b7 SYMBOL D1 = b6
SYMBOL Temp = W4 SYMBOL D4 = b9 SYMBOL D3 = b8
SYMBOL R1 = W5 SYMBOL rr = b11 SYMBOL R = b10
SYMBOL index = b12
SYMBOL R2 = 5100  ' ie. 510.0 ohms

'Readadc10 C.4, ADCvalue2
adcvalue2 =636  ' test for R1 310 to 0ohms   636 t0 1023 ' ADCvalue2 = R2/(R1+R2)x1023

X2 =  adcvalue2 *10
inX2 = $FFFF /X2 : Temp = $FFFF //X2+1
rr = X2 //10 : X2 = X2 /10
FOR index = 1 TO 3
inX2 = inX2 *10 : inX2 = Temp /X2 +inX2
r = inX2 //10 *rr
Temp = Temp //X2 *10 -r
NEXT index
inc inx2

R1 = R2 *11 **60949 **inX2 -R2      ' R1 = R2x1023/ADCvalue2-R2

BinTOASCII R1 ,D4,D4,D3,D2,D1
sertxd(" R1 = ",D4,D3,D2,".",D1,cr,lf)
end
 

hippy

Technical Support
Staff member
From another forum post the 24-bit HX711 differential ADC was mentioned. That might be of interest because it seems designed for load-cells in everyday products which are usually styled in some sort of Wein Wheatstone Bridge configuration. I was thinking about something similar but wasn't sure how it could be implemented.

Wheatstone - That's the word I was desperately trying to remember!
 
Last edited:

mortifyu

New Member
Hi mortifyu,
here's some code to try for the cheap version you could use it at 3v and a precision resistor not really required just enter the value...
Your code is pretty cool. Thanks for going to the effort, I genuinely do appreciate it.

I am pretty sure (although still browsing the finer details of numerous datasheets, now inclusive of Hippy's suggestion of HX711) I am going to go with an external ADC. Thus far the MCP3421 in singled-ended mode appears to be one of the best fits regards to the math and truly achieving the 0.1 ohm resolution I am looking for. This will then leave the accuracy coming down to my electronic design. Reference to the image I posted in POST #1, R1 will be raised to 1K or in practice at worst I may end up having to suffer with the current expense of using 510R and R2 shall be the resistor under test.

However I am VERY open to any alternative suggestions at this point. I am reasonably confident I should be able to get away without necessarily using instrumentation grade Op-Amps or 'In-Amps' as they are known as earlier suggested by AllyCat in POST#24.



Regards,
Mort.
 

mortifyu

New Member
Ok...

I have decided to go pretty extreme with this project and to put it bluntly, I feel I have now chewed off more than I can swallow (in the programming side of things).

The ADC chip I have gone with is a LTC2485. A 24-bit ADC that returns a result via I2C. This chip is rather impressive, does quite a stable job with my attached circuit and is very simple to get data returned. My very simple program reliably returns a repeated conversion result.

I am very confident this setup is mathematically more than capable of achieving 0.1 ohm resolution and coupled with my appropriate reference circuit is demonstrating stable accuracy.

The Reference voltage applied to the LTC2485 is a stable 5.000VDC showing an almost negligible amount of noise of around +/- 300-350μVDC.

This chip outputs 32bits of data. The conversion result I need to work with is from bit6(LSB) to bit29(MSB) from what I read in the datasheet.

Circuit diagram: View attachment 08M2 - LTC2485 - MAX6126AASA50 - PCF8574T - QC2004A - 0.1ohm meter - 600dpi.png

Code:
Init:
HI2cSetup I2CMASTER, $48, I2CFAST, I2CBYTE

main:
hi2cin (b1,b2,b3,b4)

sertxd("LTC2485: ",#b1," ",#b2," ",#b3," ",#b4,cr,lf)

pause 200    'This brief delay is required between conversion requests from LTC2485.

goto main
This simple program returns:

R2 @ 0.1 ohms (measured 0.12 ohms)
b1=128, b2=5, b3=252, b4=185 or in binary, 10000000 00000101 11111100 10111001

R2 @ 330 ohms (measured 329.2 ohms)
b1=159, b2=201, b3=186, b4=172 or in binary, 10011111 11001001 10111010 10101100

The underlined component being the 24-bit conversion result I need to work with.

Bits 31 & 30 are essentially STATUS bits and bit5 to bit0 are sub LSB's that are ultimately insignificant noise.

At this stage I feel totally lost trying to programmatically extract the conversion result and then turn it into the desired figures to display on the LCD.

Can someone please help me with the code required to achieve my goal?


Once again, thanks in advance guru's.




Regards,
Mort.
 

hippy

Technical Support
Staff member
The first thing to do would be to determine what the mathematical 'R = f(Nadc)' function is for converting from the ADC reading to an actual resistance value, with scaling to make R a scaled integer.
 

mortifyu

New Member
If I understand what you are asking...

16,777,215 is MAX ADC value

6130 = 0.1ohms

8,333,034 = 330ohms.

Reference to this...
Code:
Init:
HI2cSetup I2CMASTER, $48, I2CFAST, I2CBYTE

main:
hi2cin (b1,b2,b3,b4)

sertxd("LTC2485: ",#b1," ",#b2," ",#b3," ",#b4,cr,lf)

pause 200    'This brief delay is required between conversion requests from LTC2485.

goto main
To extract the 24bit value to b5, b6 & b7 to work with, I think I need something like...
Code:
.
.
If b1 bit 5 set then 
    setbit b5, 7
else
    clearbit b5, 7
endif
.
.
.
If b4 bit 6 set then
    setbit b7, 0
else
    clearbit b7, 0
Now my problem returns to the massive number math.
Because of this I have now started working on writing a STD PIC program to be a dedicated math co-processor for this one purpose that also communicates on the I2C bus. (Yet another learning curve). I am getting there, but doing it this way is adding cost to the project.


Regards,
Mort.
 

Jim-TX

New Member
I think <he says slowly> I see what you are doing. I was slowly coming up with the same method for bit-shifting the four bytes into the needed three bytes of data.

Looking at it though... could your If/Then be made a bit easier? Start with a statement like b5 = 0. Then could you eliminate the 'else' part of your code? If I am reading it correctly, you are either setting the bit to a 1 or 0. If it is 0 to start with, you don't need to set it to 0.

Just my .02 worth… but I'm not as code-fluent as some of these other fellas...
 

mortifyu

New Member
I think <he says slowly> I see what you are doing. I was slowly coming up with the same method for bit-shifting the four bytes into the needed three bytes of data.

Looking at it though... could your If/Then be made a bit easier? Start with a statement like b5 = 0. Then could you eliminate the 'else' part of your code? If I am reading it correctly, you are either setting the bit to a 1 or 0. If it is 0 to start with, you don't need to set it to 0.

Just my .02 worth… but I'm not as code-fluent as some of these other fellas...
Hi,

You are correct, however, if the routine continuously gets repeated...




Regards,
Mort.
 

Jim-TX

New Member
...then have the statement...

b5 = 0

right before you drop into the routine... ?

I guess without seeing the code I can't know how you are doing things.
 

hippy

Technical Support
Staff member
Now my problem returns to the massive number math.
Because of this I have now started working on writing a STD PIC program to be a dedicated math co-processor for this one purpose that also communicates on the I2C bus.
It should be fairly easy to do the big maths in the PICAXE. From earlier it seemed -

R2 = ( Nadc * R1 ) / ( 1023 - Nadc )

And for the 32-bit ADC reading from the LTC2485...

R2 = ( Nadc * R1 ) / ( $FFFFFFFF - Nadc )

You can choose an R1 value which makes that multiplication a simple left bit shift, eg 256R is a left shift 8, or use repeated addition, and the division can be done by repeated subtraction.
 

mortifyu

New Member
...then have the statement...

b5 = 0

right before you drop into the routine... ?

I guess without seeing the code I can't know how you are doing things.

And yes you are correct in your idea.

The Code I wrote was more or less demonstrating what I thought was the right initial approach to the drama at hand.


Regards,
Mort.
 

hippy

Technical Support
Staff member
Perhaps easy for you my friend.
I am running out of hair
I may be able to help there, but a prerequisite is proving your readings are what one would expect. If they aren't then any attempted implementation to reverse those reading is simply wasted effort.

I can't get your readings from Post #30 to correlate with the resistances you are reading ...
R2 @ 0.1 ohms (measured 0.12 ohms)
b1=128, b2=5, b3=252, b4=185 or in binary, 10000000 00000101 11111100 10111001

R2 @ 330 ohms (measured 329.2 ohms)
b1=159, b2=201, b3=186, b4=172 or in binary, 10011111 11001001 10111010 10101100
Perhaps that's simply not knowing what R1 is being used ?

It would also be worth posting a full circuit diagram seeing as we seem to have moved on from where we started.
 
Top