Working with a Load Cell and an Arduino

We built a system that uses eight air-clamping cylinders (McMaster-Carr 62185K64) to push down on a piece of glass to seal it to a sidewall. A number of times, the glass has cracked. So, this project is an attempt to come up with an inexpensive way of measuring how many pounds of force the cylinders are exerting.

The sensor that we want to use is a load cell (an arrangement of strain gauges). The specific load cell that we're using is the FX 1901 Compression Load Cell. We bought ours from Mouser for $30.

Load cells only make a very small change in voltage, so you have to use an instrumentation amplifier to increase the voltage to something we can use. The specific instrumentation amplifier that we're using is the Burr-Brown INA125 Instrumentation Amplifier. This also came from Mouser and cost just under $6.

The fastest way to hook everything together and see if it would work was to use an Arduino board and use the computer for readout. These boards can be purchased for around $30.

Here is a basic schematic of what we were trying to do.

schematic

Here is how everything looked hooking up all the parts.

breadboard

Once everything is hooked up, we just needed to write a program that would read analog pin 0 on the arduino, since that's where we hooked up the output of the amplifier.

// Arduino with load cell

// Put two known loads on the sensor and take readings. Put those values
// here.
float aReading = 192.0;
float aLoad = 15.0; // lbs.
float bReading = 344.0;
float bLoad = 24.3; // lbs.

long time = 0;
int interval = 500; // Take a reading every 500 ms

void setup() {
  Serial.begin(9600);
}

void loop() {
  float newReading = analogRead(0);
  
  // Calculate load based on A and B readings above
  float load = ((bLoad - aLoad)/(bReading - aReading)) * (newReading - aReading) + aLoad;
  
  // millis returns the number of milliseconds since the board started the current program
  if(millis() > time + interval) {
    Serial.print("Reading: ");
    Serial.print(newReading,1); // 1 decimal place
    Serial.print("  Load: ");
    Serial.println(load,1);  // 1 decimal place, println adds a carriage return
    time = millis();
  }
}

Since the response of the load cell is linear, once we've set up two loads (the a and b in our code), we can just then interpolate to get a new value. Load the above code, open the serial monitor and take measurements of two known loads. Edit the values of aReading, aLoad, bReading and bLoad with those values. Reload the code to the arduino board and retest your known loads. The load should show properly. Next, try an unknown load.

Problems

The load needs to be applied to the tip in the middle of the sensor for accuracy. This will not be a problem when we're testing the cylinders since they are basically a piston coming down. However, our test loads have been some large weights. Trying to balance them on the top of a bolt centered over the sensor has been difficult and has made our test readings probably not as accurate as they could be. A better way of calibrating will be the next step.

Updated: April 2012