Pages: [1]   Go Down
Author Topic: Reading Strain Guages / Scales  (Read 1519 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

I wonder if anyone can help or point me in the direction of more help.

Background:
I am working on a project where I want to read 2 sets of scales and convert that reading in to a weight in Kg. They are to weight people, 1 scale for each foot to measure weight distribution. Accuracy is pretty important. The max weight I want to read will be 100Kg.

I have opted to go for 4 strain gauges arranged in a full bridge. The gauges I have came from a set of bathroom scales (know to work & new for this project). The scales have a max weight of 150Kg each.

I am using a TI INA125 to amplify the signal. There is a lot of information and posts about people using it, so seams a good choice? I have been following this article for hooking up the INA125:
http://www.open-electronics.org/wi-fi-body-scale-with-arduino/
I am not using the LCD display or WiFi module.

The code is in Italian and mostly appears concerned with the WiFi and display. At present I simply want to output to the serial port.
I have used the code at: (also posted below for ease).
http://cerulean.dk/words/?page_id=42
I happily get readings and they are in the right area.

So I am happy with the hardware side (mostly) and the software side.

Problem:
The problem I have is 3 fold.

Firstly I am getting readings that fluctuate somewhat. The analogue read value changes by 1-2 in what appears to be a oscillating pattern. (period of about 1.5seconds). Any thoughts or do I just need to live with it? The change appears to be happening in the INA125. Tying the analogue input to other voltage sources, such as the ref voltages on the INA125 gives stable results. Any suggestions for filtering, or changes to the circuit?

Secondly, I am not able to obtain results that agree with real world weights. I have made the changes to the code required for the reference values and tried several different values. I have also tried a smoothing using code based on the Smoothing example in the IDE. But what I am finding is the output isn't linear. So the map function results to values that don't agree with the real weights of objects. It appears better at the lower end with the heavy weight skewing the results.

Third problem, any advice on getting the output of the INA125 to run near 0volts for no load on the scale and nearer to 5 or 3.3 at full load. (100Kg).


Any thoughts, suggestions etc greatly welcomed!

Thanks,

Nick




Code:
Code:
// Arduino as load cell amplifier
// by Christian Liljedahl
// christian.liljedahl.dk

// Load cells are linear. So once you have established two data pairs, you can interpolate the rest.

// Step 1: Upload this sketch to your arduino board

// You need two loads of well know weight. In this example A = 10 kg. B = 30 kg
// Put on load A
// read the analog value showing (this is analogvalA)
// put on load B
// read the analog value B

// Enter you own analog values here
float loadA = 12; // kg
int analogvalA = 320; // analog reading taken with load A on the load cell

float loadB = 30; // kg
int analogvalB = 460; // analog reading taken with load B on the load cell

// Upload the sketch again, and confirm, that the kilo-reading from the serial output now is correct, using your known loads

float analogValueAverage = 0;

// How often do we do readings?
long time = 0; //
int timeBetweenReadings = 500; // We want a reading every 200 ms;

void setup() {
  Serial.begin(9600);
  //analogReference(EXTERNAL);
}

void loop() {
  int analogValue = analogRead(A0);

  // running average - We smooth the readings a little bit
  analogValueAverage = 0.99*analogValueAverage + 0.01*analogValue;

  // Is it time to print?
  if(millis() > time + timeBetweenReadings){
    float load = analogToLoad(analogValueAverage);

    Serial.print("analogValue: ");Serial.println(analogValueAverage);
    Serial.print("             load: ");Serial.println(load,5);
    time = millis();
  }
 
  //analogRead(A5);
  //delay(10);
  //Serial.print("analogValue: ");Serial.println(analogRead(A0));
  //delay(100);
 
}

float analogToLoad(float analogval){

  // using a custom map-function, because the standard arduino map function only uses int
  float load = mapfloat(analogval, analogvalA, analogvalB, loadA, loadB);
  return load;
}

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;
}

2nd Option:
Code:
/*

  Smoothing

  Reads repeatedly from an analog input, calculating a running average
  and printing it to the computer.  Keeps ten readings in an array and
  continually averages them.
 
  The circuit:
    * Analog sensor (potentiometer will do) attached to analog input 0

  Created 22 April 2007
  By David A. Mellis  <dam@mellis.org>
  modified 9 Apr 2012
  by Tom Igoe
  http://www.arduino.cc/en/Tutorial/Smoothing
 
  This example code is in the public domain.


*/


// Define the number of samples to keep track of.  The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input.  Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int inputPin = A0;

long loadA = 10700; // grammes
int analogvalA = 205; // analog reading taken with load A on the load cell

long loadB = 72200; // grammes
int analogvalB = 712; // analog reading taken with load B on the load cell


void setup()
{
  // initialize serial communication with computer:
  Serial.begin(9600);                   
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;         
   
  analogReference(EXTERNAL);
}

void loop() {
  // subtract the last reading:
  total= total - readings[index];         
  // read from the sensor: 
  readings[index] = analogRead(inputPin);
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array: 
  index = index + 1;                   

  // if we're at the end of the array...
  if (index >= numReadings) {
    // ...wrap around to the beginning:
    index = 0;                           
    // calculate the average:
    average = total / numReadings;         
    // send it to the computer as ASCII digits
    Serial.print("analogValue: ");Serial.println(average);
    long load = analogToLoad(average);
    Serial.print("       load: ");Serial.println(load);

  }

  delay(10);        // delay in between reads for stability           
}

/*float analogToLoad(float analogval){

  // using a custom map-function, because the standard arduino map function only uses int
  float load = mapfloat(analogval, analogvalA, analogvalB, loadA, loadB);
  return load;
}

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;
}
*/
long analogToLoad(long analogval){

  // using a custom map-function, because the standard arduino map function only uses int
  long load = mapfloat(analogval, analogvalA, analogvalB, loadA, loadB);
  return load;
}

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

* strain guage cal.xls (19.5 KB - downloaded 19 times.)
Logged

Johannesburg. UTC+2
Offline Offline
Faraday Member
**
Karma: 96
Posts: 4339
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
weight in Kg

Excuse my being picky, but a) kilograms are mass not weight and b) the abbreviation is kg not Kg    smiley-cool
Logged

Roy from ITCrowd: Have you tried turning it off an on again?
I'm on LinkedIn: http://www.linkedin.com/in/jimbrownza

Dubuque, Iowa, USA
Offline Offline
Faraday Member
**
Karma: 47
Posts: 2512
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Firstly I am getting readings that fluctuate somewhat. The analogue read value changes by 1-2 in what appears to be a oscillating pattern. (period of about 1.5seconds). Any thoughts or do I just need to live with it? The change appears to be happening in the INA125. Tying the analogue input to other voltage sources, such as the ref voltages on the INA125 gives stable results. Any suggestions for filtering, or changes to the circuit?

The datasheet for the ATMega chips will state a 10 bit precision, +/- 2 LSB accuracy. In other words the most you can rely on is 8 bit accuracy.

It seems that the appropriate route would be to add an additional ADC converter to get more bits of accuracy. I'm no expert though and also still experimenting myself.

Secondly, I am not able to obtain results that agree with real world weights. I have made the changes to the code required for the reference values and tried several different values. I have also tried a smoothing using code based on the Smoothing example in the IDE. But what I am finding is the output isn't linear. So the map function results to values that don't agree with the real weights of objects. It appears better at the lower end with the heavy weight skewing the results.

I don't think load cells are expected to give a linear curve for weight vs voltage. The thing to do would be to sample readings with different weights (0Kg, 10Kg, 20Kg, etc.), plot those using a spreadsheet, and then use that spreadsheet's facilities to find the curve of best fit. The resulting formula will give your voltage to weight conversion.

Third problem, any advice on getting the output of the INA125 to run near 0volts for no load on the scale and nearer to 5 or 3.3 at full load. (100Kg).

The solution is to balance the bridge using a resistor (resistors) between the excitation and output lines. I'm not sure that's a good idea though as any resistors you add to the bridge will introduce new problems with the difference in sensitivity to temperature of the load cell's resistors and your resistor. Best bet is to grin and bear it?
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17294
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I don't think load cells are expected to give a linear curve for weight vs voltage.

Most industrial load cells are very linear. There is usually only a zero setting requirement, usually done in software to start with a zero value "tare weight", as when you load an empty 40 gallon barrel onto the scale and just want to measure the quantity of fluid you add to the barrel, not the weight of the barrel and the material.


Lefty
Logged

Pages: [1]   Go Up
Jump to: