Digital scale (precise 0.01g)

Hello !
I need to make digital scale with precise 0.01g , I have component as below

  1. Load cell 300g
  2. Ina125p (nstrumentation Amplifiers max gain: 10,000 )
    3.MCD3424 (Analog to digital convertor 18 bit)
    4.Arduino mega2560

My question : I know Arduino have 10 bit (1024) ,so resulotion=300/1024 = 0.29 mv/step but I need 0.01 mv/step !!
so i have to use external ADC !.

#1. Can i use (Load cell 300g===>MCD3424 ==>Arduino ) make digital scale with precise 0.01g , is it possible?
#2. If it's impossible, I must use (Load cell 300g==>Ina125p ===>MCD3424 ==>Arduino ) or not? How to design circuit

This's calulation (codition #2)

This's my circuit (codition #2)

Can someone advice me, please
I'm sorry for my english is not well ! :grin:

You will not succeed in making a device which is accurate to one part in 30000 of full scale.

michinyon:
You will not succeed in making a device which is accurate to one part in 30000 of full scale.

Did you mean that I have to connect Load cell ==>Ina125p ===>MCD3424 ==>Arduino ?
:roll_eyes:

No he means you will not succeed because this is an unrealistic design requirement given the resources you have.
Are there any commercial scales like that? If so how much do they costs? Are you expecting to match this at a lower cost?

good possible however the input of your ADC needs big voltage so you will need the INA.
The loadcell power supply should come from the reference voltage as this is important the output is 10mV/V for example

@Shooter : Thanks for your advice! Can I use Vref=5 v for both of device? :grin:

Precision digital scales that I have used do not work this way.
They use a current and magnetic field to balance the weight restoring the effective load to zero.

I would not use Vcc (ie, ARef = 5V) for anything requiring any kind of precision. Noise, variations due to loads and digital switching noise.

The balance thing is the way to do it. You can pick off the difference signal and filter out all the noise.

I would not use Vcc (ie, ARef = 5V) for anything requiring any kind of precision. Noise, variations due to loads and digital switching noise.

If I don’t use Aref=5V , what could i use refer ?

This is my circuit

This is code

#include <Wire.h>
#include "MCP3424.h"


// Configuration variables for MCP3424
#define address  0x69 // address of this MCP3424. For setting address see datasheet
byte gain = 0; // gain = x1
byte resolution = 2; // resolution = 16bits

MCP3424 ADC1(address, gain, resolution); // create MCP3424 instance.

// Set the software mode and set the analog pin
int calibrate = 1; // 0 = Output to Processing Application, 1 = Calibration mode
int i = 0;
// Low end of the test load values
float loadLow = 0.00; // measured low end load in grammes from good scales
float analogLow = 242.65;; // analog reading from load cell for low end test load
// High end of the test load values
float loadHigh = 142.55; // measured high end load in grammes from good scales
float analogHigh = 708.84; // analog reading from load cell for high end test load
// This is used when you change the load cell platform to something else that weighs
// different and the load is no longer on zero. Add an offset to set to zero.
float loadAdjustment = 0;  // Adjust non loaded load cell to 0
// Values for the analog sample buffer for running average to smooth analogue reads
 int samplesBuffer = 50; // Should be the same as the number of samples
float analogSamples[50] = {0}; // Number of analog samples to average and set to 0
int lastSampleIndex = 0; // Last analog sample
float sampleBufferTotal = 0; // The sum of all the samples held in the buffer
float analogSamplesAverage = 0; // Running average of the sum of the buffer
// Results plot or display frequency
long time = 0;  // Set time to mark start of delay
int plotDelay = 10; // Time gap between plots for display or graph
void setup() {
  if (calibrate) {
 //   Serial.begin(9600);  // Set a slower boadrate for calibration
    plotDelay = 1000;  // Slow the readings output to display for calibration
  } else {
//Serial.begin(115200);  // Set a faster baudrate for Processing Application
 // Serial.begin(9600);  // Set a slower boadrate for calibration
  }
     Serial.begin(9600);
     Wire.begin(); 
  }

void loop() {

 float analogValue = ADC1.getChannelmV(0);
  // Add new analog reading to buffer and return oldest reading
 float oldestSample = addSample(analogValue);
  // Get running average, pass the latest and oldest analog sample reading
  analogSamplesAverage = runningAverage(analogValue, oldestSample);
  
  if(millis() > time + plotDelay){
    // Convert analog value to load in grams
    float loadGrams = mapfloat(analogSamplesAverage, analogLow, analogHigh, loadLow, loadHigh);
          loadGrams = loadGrams-loadAdjustment ;  // Shift the load to measure from 0 load 
    if (calibrate) {// print test results
      Serial.print("Analog pin value: ");Serial.println(analogValue);
      Serial.print("Smoothed analog value: ");Serial.println(analogSamplesAverage);
      Serial.print("Scale load (grammes): ");Serial.println(loadGrams,2);
      Serial.println(" ");
     delay(50);
    } else {  // Output to Processing as such
     
     Serial.print("Load:"); Serial.println(loadGrams,2);
    // delay(500);  
    }
    time = millis();  // Set time to mark start of delay
  }
  }

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

// Function - running average
float runningAverage(float newSample, float oldSample) {
  // Add new sample and subtract old sample from the samples buffer total
  // then return sample average
  sampleBufferTotal += newSample;  // Add new analog sample
  sampleBufferTotal -= oldSample;  // Subtract oldest analog sample
  return sampleBufferTotal / samplesBuffer;  // Return average analog sample reading
}

// Function - add and remove analog samples from ring buffer, return oldest sample
// The ring buffer is used to keep track of the oldest sample.
 float addSample( float newSample) {
  // Add new analog read sample to the ring buffer and return the oldest analog reading
 float oldSample;
  if (lastSampleIndex == samplesBuffer - 1 ) { // Check if end off buffer reached
    oldSample = analogSamples[0];  // Get old analog sample from start of buffer
    analogSamples[0] = newSample;  // Add new analog sample to start of buffer
    lastSampleIndex = 0;  // Record sample index currently working on
  } else {
    lastSampleIndex ++;  // Move to next index
    oldSample = analogSamples[lastSampleIndex];  // Get old analog sample
    analogSamples[lastSampleIndex] = newSample;  // Add new analog sample
  }
  return oldSample;  // Return old analog sample
}

This picture is reading from MCP3424 ,I think that it has many noise .How to reduce noise ?

Use the internal reference voltage. On most Arduinos, that is 1.1V. It isn’t exact so you’ll have to calibrate for it, but it is very stable over time and temperature.

Use bypass capacitors liberally. A 1nF and 1uF on the ARef pin. With an Arduino, you can’t really add an isolation resistor and capacitor to the power pin to the ADC in the Arduino as suggested by Atmel, unless you are using a Freeduino.

polymorph:
Use the internal reference voltage. On most Arduinos, that is 1.1V. It isn't exact so you'll have to calibrate for it, but it is very stable over time and temperature.

Use bypass capacitors liberally. A 1nF and 1uF on the ARef pin. With an Arduino, you can't really add an isolation resistor and capacitor to the power pin to the ADC in the Arduino as suggested by Atmel, unless you are using a Freeduino.

Thanks you for your advice, Now I've changed ADC from MCP3424 ( 18 bit ) to LTC2400 ( 24 bit )
As you can see my video, i used voltage referent 3.3 volt at LTC2400 from arduino board and Vref = 5v at INA125
, used the power supply 5 v both of 2 IC but a voltage is not stable. How to solve this problem? =(

***i'm so sorry about my English is not well :blush:

The 3.3V output from an Arduino is just another DC power supply voltage. Not as stable as a reference voltage.

If you are using an external ADC, especially one that is 18 or 24 bits, you need something much better than the Arduino's internal reference. Use one of the many ICs made just to supply a reference voltage, they are much stabler and more accurate. When I mentioned the internal reference, I'd forgotten that you are using a much higher bit external ADC.

With 18 and especially 24 bits, you are going to need really, really well filtered power supplies and a very, very low noise, low offset, low drift instrumentation amplifier.

polymorph:
The 3.3V output from an Arduino is just another DC power supply voltage. Not as stable as a reference voltage.

If you are using an external ADC, especially one that is 18 or 24 bits, you need something much better than the Arduino's internal reference. Use one of the many ICs made just to supply a reference voltage, they are much stabler and more accurate. When I mentioned the internal reference, I'd forgotten that you are using a much higher bit external ADC.

With 18 and especially 24 bits, you are going to need really, really well filtered power supplies and a very, very low noise, low offset, low drift instrumentation amplifier.

Thanks you again
Now I'm using a referrence voltage Ic ( REF195 : 5.00 v) at ADC pin (V ref pin) i got a stable voltage more but i thing it isn't enough. I have some a question to ask you should i use a reference voltage to Vcc of Ina125 (amp) and Load cell ?

It's depend on you which kind of digital scale you need. A loot of different digital scales are available for different purposes .Please specify that for which purpose you need digital scale.

Are you beginning to beleve answer #3 yet?

emily66013:
It's depend on you which kind of digital scale you need. A loot of different digital scales are available for different purposes .Please specify that for which purpose you need digital scale.

But, but, but the Fifth Amendment. Don't answer unless first discussed with an attorney. :wink: :wink:

I have a little scale that measures down very, very fine resolution. I cannot move near it, or put it in the path of a fan or ventilation system. If I breath over it, condensation from my breath changes the reading.

Do you really need that kind of sensitivity? If so, you might just buy a commercially made scale and adapt it to your purpose.

i have made it and its not really impossible.

I have calibrated and tested the scale with F1 class weights and it's not so bad. Zero tracking is already missing

shooter:
good possible however the input of your ADC needs big voltage so you will need the INA.
The loadcell power supply should come from the reference voltage as this is important the output is 10mV/V for example

emily66013:
It's depend on you which kind of digital scale you need. A loot of different digital scales are available for different purposes .Please specify that for which purpose you need digital scale.

I see you linked elite scales, did you have any issues with their customer service? Scales work fine but their deliveries and invoicing process was off for us, we ended up using Precisa and then switching to Sartorious