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=42I 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:
// 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:
/*
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;
}