Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Attiny85/Atmega32u4 internal differential ADC to replace HX711?

Status
Not open for further replies.

harvie

Full Member level 1
Full Member level 1
Joined
Sep 10, 2014
Messages
98
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,288
Location
Prague
Activity points
2,486
Hello,
i've recently found that Attiny85 and Atmega32u4 come with differential ADC capabilities.

I was messing with load cells (strain gauge wheatstone bridges) used as weight/force sensors. Usualy people are wiring these with HX711 ICs, which is 24bit differential ADC made just for these purposes. I wonder if i can instead connect the load cell directly to differential ADC of atmel. (Given that i will only get 9 bits of resolution).

Do you think this will give me some usable readings?
 

HX711's input voltage range is +/- 20 mV (40mV) or +/- 40mV (50mV).

What do you think your Arduino's ADC VREF+ (AREF) should be?
 

Hi,

Divide the problem/questions in two parts:
The ADC and it's specifications ... and your application with your requirements.

The ADC:
I used the differential mode of AVR's ADCs.
--> All I can say: They work as described/specified in the datasheet.

The ADC does not care if the signal input is a strain gauge or any other source. It mainly depends on voltage, current, impedance.

Your application/requirements:
You need to decide the requirements first (with values, units, tolerances), then you can compare them with the specifications of the ADC. This will show whether the ADC is suitable for your application or not.

--> For some strain gauge application the ADC may be suitable, for other strain gauge applications not.

***
Side note to the "24Bit" resolution:
There is noise, there is temperature drift, there is drift with time, there are unlinearities and even more errors...all in the strain gauge, ADC, amplifiers, resistors, voltage reference...).
In most strain gauge applications I have seen the overall performance was less than 9 bits. In some advanced professional designs one maybe get to 12...14 bits (12 bits means 0.025%). 24bits is definitely out of reach.
(I see the "24 bits" just as a marketing value, they are not useful)

Klaus
 

HX711's input voltage range is +/- 20 mV (40mV) or +/- 40mV (50mV).

What do you think your Arduino's ADC VREF+ (AREF) should be?

Does it mean that when i set AREF to 40mV, i will get approximately the same behavior as HX711?

Also the atmel has some kind of gain setting, i am not sure how that applies to AREF.
 

You need to check your AVR datasheet for the minimum value of AREF that you can use.

If say, min value of AREF that can be used is 2.5V then you can only feed max 2.5V input into your AVR's ADC input and 2.5V input will result in 1023 raw ADC value.

If your Load Cell gives 2mV/V with 5V excitation voltage then output for the max load will be 10mV (2mV/V * 5V) = 10mV.

Are you sure you can read this 10mV or say 1mV from your Arduino?
 

Ok, so i've been doing some tests with Arduino ATMega 2560.

I've used ADMUX = 0b10001011 which means following:

internal 1.1V reference
adc0 negative, adc1 positive
200x gain

It got me resolution of 0.01 mV per step. With noise fluctuating around +-0.2 mV with differential pins shorted together.


Here is the arduino mega code:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
uint8_t low, high;
 
void setup() {
  Serial.begin(9600);
  //ADMUX = 1<<REFS0;                //choose AVCC for reference ADC voltage
  ADMUX = 0b10000000;                //choose internal 1.1V for reference ADC voltage
  ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);    //enable ADC, ADC frequency=16MB/128=125kHz (set of prescaler)
  ADCSRB = 0x00;
}
 
void loop() {
 
  Serial.println(read_differential());
  delay(100);
}
 
//int16_t read_differential() {
int read_differential() {
  //ADMUX |= 0b010000;             //set MUX5:0 to 010000. Positive Differential Input => ADC0 and Negative Differential Input => ADC1 with Gain 1x.
  //ADMUX |= 0b001001 ;            //set MUX5:0   adc0 adc1 10x gain
  ADMUX |= 0b001011 ;              //set MUX5:0   adc0- adc1+ 200x gain
           
  ADCSRA |= (1<<ADSC);            //start conversion
  while (ADCSRA & (1<<ADSC));     //wait untill coversion be completed(ADSC=0);
 
  low = ADCL;
  high = ADCH;
  if(high & (1<<1)){              //in differential mode our value is between -512 to 511 (not 0 to 1023). it means we have 9 bits and 10th bit is the sign bit. but because
    high |= 0b11111110;           //the number of ADCH and ADCL bits are 10, for signed number we dont have repeatition of 1 in "ADCH" byte.
  }                               //so we repeat 1 Ourselves.:)
  return (high << 8) | low;       //arrange (ADCH ADCL) to a 16 bit and return it's value.
}




My only concern now is how this performance compares to typical precision needed to read strain gauges or how it's different from precision/noise commonly achieved by HX711.
 
Last edited:

Just did similar test with HX711 module at maximum gain of 128

Got step around 0.0015 uV, with input pins shorted the noise was causing fluctuation of +-0.1 uV

So i am pretty confident that you can get readings with precision at least 1uV, probably more.

Also that means that HX711 has approximately 2000 times better precision than differential ADC of atmega2560. (Take this with grain of salt, i didn't tested it in controlled environment, just on my kitchen table with cheap arduino mega clone and chinese HX711 module in breadboard. Pretty much worst possible case. Also note that atmega has some kind of low-noise mode in which it will put whole uC to sleep while taking ADC measurement. I DID NOT USED THIS, maybe that will increase the achievable precision even further.)


I've been also doing tests with four 120 ohm resistors (metalic film ones from cheap resistor set). Made wheatstone bridge from these resistors and then tried to heat one of the resistors with flame of the lighter for a split of a second. Resolution of atmega was MORE THAN ENOUGH to capture the heat affecting the resistance. But the change of voltage was immediately 0.1 to 10 mV depending on how much i heated the resistors. It also reacted very well when i simply hovered tip of my soldering iron next to one of the resistors (without touching it) or even to heat of my finger when i touched it, or heat of my breathe.
 
Last edited:

Hi,

So i am pretty confident that you can get readings with precision at least 1uV,
1uV? Including errors like noise, thermal drift, drift with time, ... and there is linearity error, and other errors .

I see no chance for your expected precision.

Klaus
 

@KlausST Yes. you are true. There is thermal drift. I initialy noticed just the high frequency noise and didn't realized there is thermal drift. So i just went back and checked again.

When i heat the HX711 with lighter flame, it drifts by about 3 uV. And when i connect 120ohm load (wheatstone bridge) to the module power output it causes offset of 30 uV!!! But this is probably due to module not having proper differential design, since the current does not even flow through the chip. It just gets induced on the board. But i guess it's important issue to tackle, when doing such precise measurements. Chinese module has just randomly laid traces, differential "pair" not being parallel, no ground plane between differential pair and power traces, etc...

So i would say +-3uV is worst noise/drift you will get from HX711 in semi-extreme temperatures. Given that your PCB is properly designed. Otherwise it can get +-30uV or worse. Which makes it only like 60 times better than that atmega.
 

Hi,

What you see now maybe are mostly thermocouple effects.
I expect the strain gauge to drift more, and I expect it to introduce most errors at all.
I've read that strain gauge (maybe in combination with the mechanics) also introduce some hysteresis errors.
But I could not verify this.

*****

I just recognized that you talk about 1.1V internal reference.
Try to avoid this, try to use ratiometric measurement instead. This means that the strain gauge supply depends on ADC reference ( or vice versa). With this the reference voltage drift will not be introduced as error.

If you don't use ratiometric measurement, then you get two additional error sources.
* reference voltage drift with time and temperature
* strain gauge supply voltage drift.

I've seen circuits where the strain gauge is supplied with VCC. But VCC is far from being precise.
It will not only drift with time and temperature, it will also be noisy and drift with load current.
Errors in the range of 5%FS is not unusual....and this error is fed 1:1 to the strain gauge measurement.

If you use lengthy cables, then use EMC filters and line voltage suppression.
HF suppression down to nyquist frequency needs to be done on the analog side. Lower frequency may be suppressed by software.
For digital filters to work properly you need a fixed, jitter free sampling rate.

Klaus
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top