HX711-based milliohm meter - Page 1
Forum section: electronics / projects

author: dannyf
author_rank: Super Contributor
timestamp: December 26, 2014, 10:44:37 pm
content: I just found a HX711 in my box of junk parts. It is a 24bit adc, primarily designed for weight scales.The module I have seems to have two imports wired out, but not symmetrical for some reason. The plan is to configure the two channels in serial, with the appropriate padding. One channel would be a precision resistor and another would be the dut.The adc chip has fairly low spec, so I wouldn't expect miracles but it would be interesting to see if it works out.More to come.

author: jaxbird
author_rank: Frequent Contributor
timestamp: December 26, 2014, 11:05:35 pm
content: Quote from: dannyf on December 26, 2014, 10:44:37 pmUsually I throw out these obscure Chinese chips because of lack of documentation. But if you got sufficient docs then I guess it could make a nice ratio based meterOtherwise I have at least 5 8051f350 in my uC box, I'll send you one if you want it.

author: dannyf
author_rank: Super Contributor
timestamp: December 26, 2014, 11:41:01 pm
content: I have used F350s before, very nice chips, particularly with both Vrefs out.

author: dannyf
author_rank: Super Contributor
timestamp: December 27, 2014, 10:09:03 pm
content: Here is a quick schematic.The module I used was sourced from ebay, and was poorly designed and poorly documented. It has six pins to interact with your circuit,1) E+/E- are the positive / negative engerizing terminals.2) A+/A- are for channel A (128x and 64x gain). the pins are unbalanced in that only A+ has a 1.2k resistor.3) B+/B- are for channel B (32x fixed). The pins are unbalanced in that only B= has a 1.2k resistor.The original module was meant for weight scales, so it is designed to work with a bridge, and with only 1 channel (typically Channel A).I want mine to be ratiometric so I have to use both channel A and channel B.So here is my wiring:

author: dannyf
author_rank: Super Contributor
timestamp: December 27, 2014, 10:17:58 pm
content: The chip has some interesting spec:1) padding: it requires minimum and maximum common mode on the adc pins. I think it is from GND+1.2 to AVDD-1.3. As the module can only be run from a 5v source (due to a poorly designed Vfb circuitry where a 20k/8.2k divider ratio was used -> AVdd=4.3v). So I have to 'pad" the circuit and to keep the adc pins to be reasonably close to the middle (about 2.1v).2) channel selection: the full scale voltage is very low. For Ch A, it is either 4.3v/128=33mv or 4.3v/64=67mv (or half of that for bipolar readout). For Ch B, it is about 4.3/32=134mv.So it makes sense, in order to maximize resolution, to put the precision resistor on Ch B, and the dut on Ch A.3) precision resistor selection: The current going through the resistor string is about 4.3v/20k=0.2ma. The maximum bipolar reading on Channel B is 134mv / 2 = 70mv. So the maximum value of Ch B resistor is 70mv/0.2ma=350ohm. I happen to have a 82ohm resistor so that's what I am going to use.

author: dannyf
author_rank: Super Contributor
timestamp: December 27, 2014, 10:30:07 pm
content: Here is the data sample, about 2500 of them (the sampling rate is very low, about 0.5sps).The numbers are the adc readings, at a gain of 1 (Ch A was 64x and Ch B was 32x).82ohm readings: average - 67789, std dev - 1.874, or 27.6ppm;1ohm readings: average - 777.6, std dev - 0.795, or 1021ppm.as the design is ratiometric, we expect the adc readings to be proportional to their expected resistive readings. 67789/777.6=87.17x, vs. 82/1=82x. Close but not exactly the same.

author: dannyf
author_rank: Super Contributor
timestamp: December 27, 2014, 10:33:28 pm
content: you will notice that about 2/3 into the test, the numbers start to go haywire - i moved the testing fixture and it may contributed to that.As a matter of fact, if I had used just the first 1500 samples, the performnace would have been much better.Also, I didn't use a kevin clip so that may have contributed to the worse performance on the 1ohm dut.

author: dannyf
author_rank: Super Contributor
timestamp: December 27, 2014, 10:38:11 pm
content: Here is the actual wiring.The mcu is a LM4F120 launchpad, running at 1Mhz and 3.3v.The HX711 module runs at 5v. The level translation was done by two 1k resistors on the SCK and DOUT pins.The resistor pair can be seen on the left.

author: dannyf
author_rank: Super Contributor
timestamp: December 27, 2014, 10:44:06 pm
content: Potential Modifications:1) to increase the lower-end of the measurement range, you can run the resistor string hotter. For example, two 1k resistors can be used and you would be running at 4.3v/2k=2.2ma. Correspondingly, you have to lower the precision resistor on CH B so that it remains within the full scale of that channel.2) resolution: 1 ohm translates into adc readings of 777 - 779, at gain of 1x. So at a gain of 64x, each lsb would be 1ohm / 778 / 64 = 0.02 milliohm; or 0.01 milliohm at 128x gain. More than sufficient for most applications.3) oversampling: I didn't do this, but you can keep the raw adc data in the calculation so to effectively oversample the adc.

author: dannyf
author_rank: Super Contributor
timestamp: December 27, 2014, 10:47:47 pm
content: The raw adc data is actually quite noisy. I suspect that this is a 16bit adc with pga.Once you take out the last few digits, it is fairly stable.Overall, it was fairly easy to get it up and running. The code is fairly straight forward in C and compiled under Keil. Not much trouble getting it to run.I got mine a while back and forgot how much I paid for it. I just checked ebay and those things go for a couple dollars shipped. It is pretty good value in my view.

author: dannyf
author_rank: Super Contributor
timestamp: December 27, 2014, 10:49:14 pm
content: As this is a weight scale adc, I suspect that you can buy a weight scale, with its lcd display and everything, and hack it to be a milliohm or millivolt meter - same principle.That would be interesting to attempt.

author: Kalvin
author_rank: Super Contributor
timestamp: December 27, 2014, 10:58:17 pm
content: Averaging ie. oversampling is a method to reduce the random noise in measurements in order to gain back those lost bits.In principle, if you take four measurements and compute the average, you will gain one extra bit. If you take 16 measurements and compute the average, you will gain two extra bits etc.Atmel has a nice application note "AVR121: Enhancing ADC resolution by oversampling" which discusses this in more detailhttp://www.atmel.com/images/doc8003.pdfBr,Kalvin

author: dannyf
author_rank: Super Contributor
timestamp: December 28, 2014, 09:02:50 pm
content: Here is the data sample, straight out of the chip (the only processing is 2's complement, not applicable here).The blue lines are for 64x gain, and the pink lines are for 32x gain.The ratio is 43x (43.3x) over about 500 samples.Deviation is fairly small, looks to be 50 lsbs short term. Reasonably respectable.However, the killer is the chip's long-term drift. The blue lines drifted 400 lbs, about 0.15%. Not acceptable for a 24bit adc in my view.

author: Kalvin
author_rank: Super Contributor
timestamp: December 29, 2014, 09:27:01 am
content: This is just guessing: Could the bridge and its components cause this drifting. I mean that resistors temperature and resistance might change as you pass current through the components. One other thing that came to my mind is possibility of thermocouple ie. Seebeck-effect due to different metals affecting each other causing voltage difference due to temperature change. Of course, the ADC itself might cause the drifting, too.

author: dannyf
author_rank: Super Contributor
timestamp: December 29, 2014, 12:11:59 pm
content: The current is less than 1ma (0.2ma to be exact). It would be hard that self-heating is the issue here.I think the adc is the problem.

author: dannyf
author_rank: Super Contributor
timestamp: December 29, 2014, 12:12:55 pm
content: Don't get me wrong - the millimeter will still work. The drifting we are talking about are quite low and once you have "degained" the adc readings, it is practically gone.

author: Kalvin
author_rank: Super Contributor
timestamp: December 29, 2014, 03:56:27 pm
content: QuoteThis small drift 0.15% just made me wonder if there could be some other reason other than ADC itself behind the drift. Anyway, finding out whether it is the ADC or the resistor bridge causing the drift can be found out by carefully heating/cooling the ADC chip or bridge components a little. Yet, the 0.15% error is quite low anyhow

author: wraper
author_rank: Unknown
timestamp: December 29, 2014, 04:19:55 pm
content: Likely internal bandgap reference is not very stable. As I understand, when using internal voltage regulator (+external transistor), that should cancel out measurement drift as bridge supply voltage should drift by the same ratio as reference. You could check how much reference voltage drifts on pin 6 and if bridge supply voltage drifts by the same ratio.

author: dannyf
author_rank: Super Contributor
timestamp: December 29, 2014, 04:20:23 pm
content: I will experiment more when I get more time.

author: dannyf
author_rank: Super Contributor
timestamp: January 03, 2015, 02:30:38 am
content: QuoteAs promised, I did.Set-up: HX711 module controlled by a LM4F120, data out via serial to the PC, reading CH_A and CH_B alternately.The experiment started at room temperature. At about count 300, I put a hot iron on the chip, separated by four layers of paper towl. The iron is at least 275c and through the paper towl, it is too hot to hold onto the tip with my finger.Put the tip on the chip - the rest of the circuit not impacted by the hot iron.At about count 400, the paper towl had a burned mark on it and started to smoke. I took the tip off the hx711 - at that point, the hx711 was hot to the touch - 85C at least.Throughout the whole process, the reading is uninterrupted.The experiment stop'd at count 750.The adc readings are then charted below.You can calculate the ppm for both channels.Two things surprised me:1) the two channels are negative correlated - I kind of observed that in earlier charts but this is the most obvious. This would make using one of them as a reference to measure the other difficult.2) the two channels have quite different tempco.Interesting, in a bad way.

author: Kalvin
author_rank: Super Contributor
timestamp: January 03, 2015, 12:52:08 pm
content: What happens if you heat only the bridge components instead of the ADC? Does it make the results drift?If the ADC has a built-in temperature sensor, you could possibly measure ADC's temperature and apply precomputed temperature compensation coefficients for the measurement values, after which you should get pretty good results.Br,Kalvin

author: Kalvin
author_rank: Super Contributor
timestamp: January 03, 2015, 12:55:20 pm
content: Of course, you could provide a constant temperature to the ADC which would solve temperature related drifting problem. Similar technique is used in high precision, temperature stabilized oscillators TCXO.

author: dannyf
author_rank: Super Contributor
timestamp: January 03, 2015, 01:09:20 pm
content: That would be purely a test of the resistors' tempco.What troubles me is the negative correlation - which kills any ratiometric approach.

author: Kalvin
author_rank: Super Contributor
timestamp: January 03, 2015, 01:24:32 pm
content: Heating the ADC from room temperature to finger-burning temperature is quite a big change. As I recall, the original problem was the drifting in room temperature when a resistor was applied. That's why I was also interested in seeing the temperature effect on the bridge components and whether there might be any galvanic voltage sources which could explain the drifting. However, this galvanic voltage source is just my pure speculation, but as we are dealing with a high precision measurements, even small thermal/galvanic voltage sources may ruin the day.Br,Kalvin

author: dannyf
author_rank: Super Contributor
timestamp: January 03, 2015, 01:56:40 pm
content: There is no bridge to speak of: the set-up is ratiometric. As such, it requires positive correlation, preferred 100% correlation - aka the same tempco.Anyway, here is the iron applied to the resistors, starting at count 300 and off at count 400.I have to say that I cannot see a difference here, vs. the prior chart.

author: Kalvin
author_rank: Super Contributor
timestamp: January 03, 2015, 02:02:03 pm
content: Quote from: dannyf on January 03, 2015, 01:56:40 pmDo I understand this correctly that the temperature drift stays the same whether you heat only the ADC or only the bridge components?

author: dannyf
author_rank: Super Contributor
timestamp: January 03, 2015, 02:09:32 pm
content: I don't think so.When the chip was heated, Ch B went from 2.1735MM to 2.1715MM.When the resistors were heated, Ch B went from 2.175MM to 2.157MM, a much wider variation.Now, I cannot be sure that the temperature changes are the same but the iron was at the same setting and the heating time is roughly the same. So I think the temperature changes are reasonably comparable.

author: Kalvin
author_rank: Super Contributor
timestamp: January 03, 2015, 02:59:10 pm
content: You are correct. I was just looking at the A channel drift, but I didn't look at the B channel drift carefully enough which is 10x more when heating the "bridge" components compared to heating only the ADC.

author: Kalvin
author_rank: Super Contributor
timestamp: January 03, 2015, 03:18:53 pm
content: I found this excellent article by late Jim Williams "Minimizing thermocouplesmaintains 20-bit DAC precision":http://m.eet.com/media/1142215/82758.pdfThe article is applicable for the 24-bit ADC as well.

author: dannyf
author_rank: Super Contributor
timestamp: January 14, 2015, 12:33:26 pm
content: Just wanted to circle back on this.Here is a test on a 1ohm (nominal) resistor, detected as 0.954645ohm by the meterThe readings fluctuates within about 65ppm of the mean, over a short period of time -> 50 readings x 0.5second / reading = 25 seconds.Filtering can drastically reduce that ppm number, by the way, at the expense of slower responses.I would conclude by saying that 1) the concept works; and 2) it doesn't work on this particular adc module -> too sensitive to temperature and the wrong way correlation between the A/B channels makes it impossible to hold calibration.

author: Kalvin
author_rank: Super Contributor
timestamp: February 28, 2015, 11:38:38 am
content: I didn't want to hijack theoriginal el cheapo micro-ammeter threadso I will post my comments here instead as they are related to the HX711.Quote from: Kalvin on February 27, 2015, 10:09:50 amQuote from: dannyf on February 27, 2015, 11:34:58 amQuote from: Kalvin on February 27, 2015, 08:28:02 pmQuote from: dannyf on February 27, 2015, 10:41:28 pmThe initial plan it to device an analog multiplexer controlled by the microcontroller so that the HX711's A and B inputs could be interchanged, optionally driven by a known reference voltage and known zero voltage. I could not find any information about the input impedance of the A and B inputs, so I must assume it to be less than 100kohms, so the resistance of the analog switches must be taken into account. Of course adding a low-offset quad op amp with high input impedance as a buffer for A and B inputs would be an option, which would make the resistance of the analog switches insignificant.Here I will now assume that selecting an analog switch device having resistance close to 1 ohms would eliminate the need for any buffering op amps. However, I am not quite sure how cheaply one can find these low resistance analog switches.The analog switches comes in variety configurations: from single switches to multiplexers. The multiplexers come typically in single and dual channel configurations. A dual-channel multiplexer has typically a good match between the switch resistance within a device.Selecting two dual 4-to-1 analog MUXes would allow quite flexible calibration operations:Code:MUX# A+ A- B+ B-0 A B Normal measurement1 B A Channels swapped2 0 0 Channels connected to zero reference3 Ref Ref Channels connected to known reference voltageDo we really need the reference voltage for the calibration, or would it suffice only to swap A and B channels for the measurement signal from time to time for calibration. If the channels should have different tempcos, one should be able to calculate the error between the channels as we switch the MUXes back and forth. Of course, using a good reference voltage for the calibration, we would get more accurate absolute measurement values.In the ratiometric measurement application like this milliohm meter, the absolute accuracy is not a concern, but the relative accuracy between the channels A and B is important.What do you think? Any suggestions?

author: JohnnyBerg
author_rank: Frequent Contributor
timestamp: February 28, 2015, 11:53:41 am
content: Isthisthe correct datasheet?Unless I'm missing something, there is no spec for accuracy and linearity?Thanks @dannyf for the measurements. As I see it, this is a pretty useless device for doing some serious ADC?

author: Kalvin
author_rank: Super Contributor
timestamp: February 28, 2015, 12:05:28 pm
content: Quote from: JohnnyBerg on February 28, 2015, 11:53:41 amHere is a chinese datasheet with a bit more information:http://www.hobos.com.cn/upload/datasheet/HX711.pdfMy chinese is not that good that I could decipher what the datasheet really says, but luckily there are some numeric information available which is comprehensible.

author: dannyf
author_rank: Super Contributor
timestamp: February 28, 2015, 12:09:50 pm
content: Kalvin: what's the application and what's your approach? Sounds like it is to use a multiplexer to calibrate the adc and then ...?JohnnyBerg: yeah. The one Kalvin linked to is better however. I basically couldn't figure out a way to deal with the opposite tempcos.

author: Kalvin
author_rank: Super Contributor
timestamp: February 28, 2015, 01:10:26 pm
content: Quote from: dannyf on February 28, 2015, 12:09:50 pmI have no particular application in my mind. I bought two modules for fun, inspired by your experimenting. Only reason to pursuit this a bit further is the mental and practical challenge whether one can push the part into its limits (say, 17-bits of accuracy) as stated in the datasheet, compensate the tempco effects using cheap compensation method, and whether one can get 17-bit accuracy using dollar range parts (in room temperature ie. in limited temperature range). Of course the easiest and most sensible way would be to buy a good 24-bit ADC and high precision voltage reference. For example, the LTC2440 costs around $5 in 1K volumes, which is not much. It needs also a good few dollar reference to be accurate.

author: dannyf
author_rank: Super Contributor
timestamp: February 28, 2015, 01:26:41 pm
content: That makes sense.I haven't seen any spec for the ADC input resistance myself but I haven't found loading to be an issue here.So an analog switch that multiplexs the input pins would work- 17 bits have a range of 128k so if you can get the switch resistance to 8 ohm or lower, 1meg ohm ADC resistance would work. Alternatively you can buffer.

author: JohnnyBerg
author_rank: Frequent Contributor
timestamp: February 28, 2015, 01:40:35 pm
content: Quote from: Kalvin on February 28, 2015, 01:10:26 pmMe tooQuoteThe refernce will be much more .. for a real 24 bit ADCRemember 24 bit = 16,777,216 count

author: Kalvin
author_rank: Super Contributor
timestamp: February 28, 2015, 02:24:03 pm
content: Quote from: JohnnyBerg on February 28, 2015, 01:40:35 pmTheLTC2440 datasheetdoesn't directly state its accuracy, but the nonlinearities and full scale errors shown on pages 5 and 6 are in range of 1 - 2.5 ppm and the figure "INL vs Output Rate" on page 7 shows linearity to be 17 to 18 bits*. The offset error looks negligible and the RMS noise figures are close to 2uV. Although the device is 24-bit ADC, the actual accuracy may be in range of 18 - 20 bits. Averaging will reduce the noise**, but it would not reduce nonlinearity error.Creating a circuit which will exhibit 120dB dynamic range and 1:1000000 accuracy requires very careful design, high quality components, and knowledge (that I do not have). Creating a design with the dynamic range of 90 - 100dB may be within my capabilities.* Edit: The figure is for the conversion rates of 2000 conversions/seconds and faster giving reduced 17 - 18 bits linearity. The figure "integral Nonlinearity vs Conversion Rate" on page 6 shows that using the slower conversion rates the nonlinearity stays quite close to 2 ppm giving the "0.0005% INL, No Missing Codes" stated in the datasheet.** Edit: On page 14 and 25 there are tables showing the effect of conversion rate vs. the effective number of bits (ENOB) available, from 17 bits up to 24 bits.

author: Kalvin
author_rank: Super Contributor
timestamp: October 21, 2015, 09:49:15 am
content: I decided to take a look at this dannyf's project. When I started working with the board I found following:- The AGND was not connected to the GND. Just added a jumper between AGND and GND make proper connection.- I changed the 8k2 ohm resistor in the VFB node to 10khm so that the AVDD is less than 4V in order to have some headroom to my Arduino board's 4.5V VDD.- I found out that the solderless breadboards are uselelss with this project, so the measurement signal wirings and connections are better to be soldered properly.- I changed the output rate from "0" to "1" giving approx 8 measurements per second.After that, I was able to achieve following using a reference resistor of 1.000 ohm and simple null-calibration:- Using 4-wire Kelvin-type measurement- Measurement time 8 hours at room temperature epprox. 21C- Initial drift was 3 milliohms- After initial drift, the variance was +/- 0.5 milliohms- Measurement current is in range 5mA - 10mA.The accuracy and resolution is quite close to a 12-bit ADC. I used the HX711's own internal reference and the power supply was derived directly from Arduino's voltage regulator without any specific filtering. I didn't test temperature sensitivity, but warming the chip with a finger did produce few milliohms drift (not too bad).Br,/KalvinEdit: Here is the plot data collected today for a period of 9 hours. The resistance is quite nicely within +/- 0.25 milliohms after initial transition. Taken the initial transition into account, the results are within +/- 0.5 milliohms.

author: dannyf
author_rank: Super Contributor
timestamp: October 28, 2015, 12:34:10 am
content: I have done more work recently on this that you may find interesting:https://dannyelectronics.wordpress.com/2015/10/25/a-hx711-based-milliohm-meter/Running the circuit at 2ma and utilizing a 10R reference resistor, the resistance readings are stable to the 4th digit (after the chip has reached thermal stability).I am starting to appreciate this little bugger now.

author: Vgkid
author_rank: Super Contributor
timestamp: October 28, 2015, 02:58:30 am
content: Thanks for the update.

author: Kalvin
author_rank: Super Contributor
timestamp: October 28, 2015, 08:29:36 am
content: Quote from: dannyf on October 28, 2015, 12:34:10 amThanks for your update. I read through you blog posting, and the results I have are in line with your measurements.Here are my measurements from the last night at room temperature of 23C. I have removed the 1K series resistor and filter capacitors from the A and B inputs. The HX711 is used in "fast" mode, so there are approx. 8 readings/s. The "fast" results are filtered using a simple running average of length 128 samples.The filtered data plot is shown below. The Y-axis range is 0.9995 ... 1.0005 ohms as the measured resistor is nominal 1.000 ohms. After the initial transition, the filtered results have variance of approx. +/- 0.05 milliohms (ie. +/- 0.00005 ohms), so the measurement resolution is within +/- 0.1 milliohms (ie. +/- 0.0001 ohms). Without averaging, the resolution is within +/- 1 milliohms (ie. +/- 0.001 ohms).The resistors used in the current measurement arrangement are quite sensitive to temperature changes, as placing the finger on the 1/4W metal film reference resistor or the 1/4W metal film resistor to be measured will change the measurement result by approx. +5 milliohms.Placing the finger on the HX711 has very little effect: the measurement reading changed less than 0.2 milliohms, so it seems that HX711 is not too sensitive to temperature changes in order to be used as a milliohm meter with the usable measurement resolution of +/- 1 milliohms and the update rate of 8 readings / s (see my previous post above).

author: dannyf
author_rank: Super Contributor
timestamp: October 28, 2015, 11:08:26 am
content: Kalvin: great work.QuoteThat's a good way to filter out the noise. But on a small mcu, the space / time requirement can be excessive.Another way to implement that is to utilize exponential smoothing:Code:uOHM_s+=(uOHM - uOHM_s) * alpha;where uOHM_s is the smoothed output (equivalent to your moving average), uOHM is the "instantaneous" measurement of the resistance, and "alpha" is the weight you give to the current measurement. The lower alpha is, the longer the "memory" of the algorithm is. using alpha of 1/128.0 for example would produce similar performance as your moving average (not quite the same but similar).For example, the chart below shows the instantaneous measurements (uOHM, red trace), 16-sample smoothed measurements (uOHM_s), and 16-sample moving averaged (uOHM_avg).Hope it helps.

author: Kalvin
author_rank: Super Contributor
timestamp: October 28, 2015, 11:33:41 am
content: Quote from: dannyf on October 28, 2015, 11:08:26 amTypically I would use the exponential weighing for the filtering, but for this particular measurement setup I decided to use true running average as it has well defined window of N samples (N=128 this time). In the final version I will use the exponential filtering, though.I am running the test code on Arduino Nano (atmega328p) with the 2.2" QVGA TFT SPI for displaying the measurement data and using the serial port for actual data logging. The TFT update using hardware SPI is still so damn slow that it affects the measurement rate a bit, but the update rate is still sufficient so that the Arduino is usable as an evaluation platform. I had those displays in my drawer, so I picked one for this project. My final hardware will be running on a STM32F103, but I wanted to get up and running fast and chose Arduino for prototyping.BTW, I tested two high power diodes 1N-something placed across the input terminals as overvoltage protection and they didn't affect the readings at all as the measurement voltage is iwell below diodes' threshold voltage. In the actual design I will use an isolated +5V/+5V DC/DC-converter and optoisolators to isolate the HX711 from the rest of the system so that the device can be powered safely from a USB-port and the measurement signals are truly floating.Edit: Using the TFT gives some possibilities here. For example, there can be two reading on the display: One is the latest measurement value, updated 8 times in a second with the resolution of 1 milliohm. The other value shown is filtered/averaged value giving resolution of 0.1 milliohms. Of course, the display could also show some other measurement statistics like low/high resistance in milliohms etc. I have also a beeper onboard which is will change its pitch according to the measured resistance.

author: dannyf
author_rank: Super Contributor
timestamp: October 28, 2015, 09:26:30 pm
content: QuoteIf you want, I can share with you an approach that I have used to quickly calculate moving average (sum actually): it takes one subtraction, one addition, and one assignment to yield a moving sum. Plus one division or one shift if you wish to get an average. The algorithm is particularly useful if you desire a long window of data.

author: Kalvin
author_rank: Super Contributor
timestamp: October 29, 2015, 06:54:51 am
content: Quote from: dannyf on October 28, 2015, 09:26:30 pmDannyf, I am doing the exponential averaging as follows using one addition, one subtraction and two shifts (when N is power of 2):int32_t sum = 0;int32_t avg = 0;...sum += new_value - (sum / N);avg = sum / N;The worst-case value stored in the variable sum will be maximum absolute value of the "new_value" times N (ie. max(abs(new_value))*N).

author: dannyf
author_rank: Super Contributor
timestamp: November 03, 2015, 12:07:28 pm
content: QuoteKalvin, that would be absolutely the right way of doing it in the digital domain: it avoids the typical pitfall that beginners usually make when porting floating point math algorithms to fixed point math. Well done.For your interest, I implemented a milliohm meter with just the attiny85 + a few resistors but no hx711:https://dannyelectronics.wordpress.com/2015/08/02/mcu-based-milliohm-meter/Obviously the resolution and precision is not in the same ball park as the one with hx711.ciao.

author: Kalvin
author_rank: Super Contributor
timestamp: November 03, 2015, 02:15:02 pm
content: Quote from: dannyf on November 03, 2015, 12:07:28 pmNice work as usual, dannyf.One ipossible improvement came to my mind: You can make your design less sensitive to the power supply variation (pseudo-ratiometric) if you consider the resistor connected between the DUT- and the ground as a reference resistor. Choose the value for the reference resistor so that it is 20 times as large as the maximum DUT. Then, you first measure the voltage across the DUT using the differential mode with the gain of 20 and then configure the ADC to measure the voltage across the reference resistor (between the DUT- and the ground) in single-eded mode. Now you should be able to maximize the resolution and make the this pseudo-ratiometric measurement insensitive to the voltage.Br,Kalvin

author: dannyf
author_rank: Super Contributor
timestamp: November 05, 2015, 02:32:06 pm
content: Kalvin, thats a good approach to try. Maybe not on the attiny but definitely a larger chip, with more pins.A dream chip to implement this on would be atmega32u (used on Leonardo and the mini). The PGA has a gain up to 200x. But not all minis have the adc0 adc1 pina routed out.Ciao.

author: Kalvin
author_rank: Super Contributor
timestamp: November 05, 2015, 02:45:48 pm
content: Quote from: dannyf on November 05, 2015, 02:32:06 pmYou do no need more pins when you use the R2 as the reference resistor. So basically you can do something like this:1. Configure the ADC to measure differential voltage across the DUT (just like you are doing now if I have understood it correctly).2. Configure the ADC so that you can measure single-ended voltage across R2.Now you should have everything needed for calculating the DUT and the measurement is not sensitive to voltage changes.You just need to select R2 so that the voltage across R2 is optimized across the measurement range. As the ADC is quitefast, you can do averaging to get good stable readings.

author: dannyf
author_rank: Super Contributor
timestamp: November 05, 2015, 03:12:37 pm
content: Kalvin, I see.The difficulty may be with adc'ng a voltage very close to gnd.The approach I have now is a series of resistors , rail to 1k to sit to 1k to gnd. The voltage across the dut is measured differentially, and at a gain of 20x. The use of the two resistors is to limit current. The use of the lower resistors is to pad the common voltage towards the middle so I get better performance.If I had replaced the lower resistors with a low value reference resistor, the common voltage would be quite close to gnd (about 200mv if a 10ohm resistor is used).I can give it a try when I get more time. Maybe a 100ohm reference can be used instead.

author: dannyf
author_rank: Super Contributor
timestamp: November 07, 2015, 09:19:33 pm
content: QuoteGood news and bad news.First, the approach works - see the simulation below, with a 10ohm reference resistor, measuring a 0.123ohm DUT. The measurement is generally independent of the supply voltage used, aside from some fluctuation in the last digit.However, on real hardware, the measurement fluctuates about 50-60mOhm, for a 1ohm DUT. Vs. 10mOHM fluctuations under the prior approach with exponential smoothing.I will play with it a little bit more to see if I can improve it - in all of its glories:https://dannyelectronics.wordpress.com/2015/11/08/a-mcu-based-milliohm-meter-version-2/The adc linearity of those attiny devices at near ground levels are amazing.

author: Kalvin
author_rank: Super Contributor
timestamp: November 08, 2015, 08:43:22 pm
content: Hi dannyf,Thanks for feedback and nice to see that it basically works.I guess that you could improve its accuracy by selecting the reference resistor as follows:- Reference resistor R2 should be 20 times the maximum DUT to be measured, because the 20x gain used when measuring voltage across DUT.For example, if the maximum DUT is 5 ohms, the reference resistor will be 100 ohms.- Reference resistor R2's current should be set by R1 so that the voltage over the R2 is close to VREF when DUT is short-circuited.Short-circuit the DUT and adjust R1 so that the voltage across the R2 is almost VREF.This will maximize the dynamic range of the measurement.Now, when you set DUT = 1 ohm resistor, the voltage across the reference resistor will be a bit less than the maximum voltage. And the voltage across the 1 ohm DUT will be measured differentially and amplified by 20, so the dynamic range will be as good as possible.Using the filtering will make reading stable.Br,Kalvin

author: dannyf
author_rank: Super Contributor
timestamp: November 09, 2015, 12:00:02 am
content: QuoteNo need to be 20x. The key to maximizing the resolution: to make sure that the voltage drop over the reference resistor is as close to the Vref selected for the ADC as possible - maybe 80 - 90% of the Vref. This approach produces the largest digit.In my case, the current is about 10ma so something close to 100R would be ideal.A sub-optimal approach, which I utilized, is to oversample. Fairly effective as well.

author: Kalvin
author_rank: Super Contributor
timestamp: November 09, 2015, 07:36:32 am
content: Quote from: dannyf on November 09, 2015, 12:00:02 amHi dannyf,You may want to get the voltage drop across the DUT also as large as possible in order to maximize the numeric value from the ADC when measuring DUT, too.For example, if you choose the reference resistor R2 to be 100 ohms, short-circuit the DUT and adjust the R1 so that the voltage across R2 is 80% - 90% of VREF, you have maximized the measuring range for the reference resistor R2. The numerical values you are getting from the 10-bit ADC is in range 800 - 900.But you may also want to obtain as high measuring values for the DUT too in order to maximize the dynamic range of the DUT as well. You are taking advantage of the 20x gain of the ADC when measuring the differential voltage across the DUT, so the maximum voltage across the DUT can be 1/20 of the VREF. That means also that the maximum voltage across the DUT can be 1/20 of the reference resistor R2. Thus, the maximum value for the DUT is approximately 1/20 of the reference resistor R2.With the 100 ohm reference resistor the maximum DUT is approximately 5 ohms, and you should get almost 5 milliohm resolution using 10-bit ADC. Oversampling by factor of 100, you should gain one extra digit ie. you should obtain resolution of 0.5 milliohms which is pretty impressive.I haven't tested this though, so I may have missed or overlooked something.Br,Kalvin

author: dannyf
author_rank: Super Contributor
timestamp: November 15, 2015, 05:27:50 pm
content: QuoteNot quite there but I can get to about 5milliohm resolution easily. The update rate is faster than my eyes can process,Quoteyou are spot on.I built a current generator out of it, if you are interested:https://dannyelectronics.wordpress.com/2015/11/12/a-digitally-controlled-current-generator/Those tiny AVRs are simply amazing.

author: Kalvin
author_rank: Super Contributor
timestamp: November 15, 2015, 05:48:30 pm
content: Quote from: dannyf on November 15, 2015, 05:27:50 pmNice gadget! I haven't been using those small AVRs yet. The Atmega328 seems to be a bit limited in the ADC compared to the Attiny85. I did something similar as built a battery capacity tester a while ago, but used op amp in the control loop and the Atmega328 producing the current controlling voltage with the PWM DAC. I have a few STM32F103 boards and PSOC 5 boards, so hopefully I don't have to struggle with the Arduino and/or Atmega328 any more

author: dannyf
author_rank: Super Contributor
timestamp: November 21, 2015, 06:51:46 pm
content: QuoteVery much so.I worked on a milliohm meter using icl7107 (or the likes), down to 1mohm.I'm working on another utilizing mcp3550/3551: 22bit adc and quite inexpensive. Good down to uohm range.The same strategy works for LTC2400 as well.

author: necessaryevil
author_rank: Regular Contributor
timestamp: November 21, 2015, 07:07:01 pm
content: The Jan 1983 elektor contains two miliohmmeter circuits. The first is just a 100 mA current source, but the second one is a pulsed current source and a sample and hold circuit. Maybe an idea?

author: darksky
author_rank: Contributor
timestamp: October 30, 2016, 05:55:05 pm
content: Hi Guys,I have played with the HX711 and can now read a resistor to an accuracy of better that 50 uohms or 0.0004% of readings.circuit is 1500ohm resistors with reference as 10 ohms but it is important to place a 0.1 capacitor accross the reference resistor and DUT.DUT range 0- 22 ohmsThie capacitor greatly elimiates noise and increases accuracy.I have also been able to write code for the arduino that allows measurement of a 10k resistor to an accuracy better that 0.5%.The idea is to place a 10 ohm resistor as the DUT measure its value then place a an unknown resistor accross that, then calculate the effect of the unnown value.I can now measure accuately from less than 2 milliohms directly and upto 10k with the parallel method. Accuracy at 10K is better than 2%.Happy to share the code and circuit with any one interested.Thees chips have a lot of potential.

author: apang99
author_rank: Newbie
timestamp: April 27, 2019, 09:33:56 pm
content: Hi Darksky:I came in late in this forum for HX711, can you please share your code and circuit with me? many thanks!