# Building a Simple Weight Scale 2018-08-12

Building a Simple Weight Scale

Not that long ago an opportunity came to learn about strain gages (load cells) and Sparkfun’s OpenScale project. I decided to acquire one of each and for the sake of speed I ordered both from Amazon. I immediately started playing with the available information, after some research and tweaks got something working, and then decided to build a small weight scale just to finish it up. What follows is a brief summary of what I did. Hopefully this work helps others down the road.

OpenScale Evaluation

The OpenScale project from Sparfun Electronics (i.e. SFE) is pretty cool and the best part is that is open source. The basic information can be found in SFE’s OpenScale Applications and Hookup Guide, and the code repository can be found in github. The code in the Github’s repository is pretty elaborated as it includes temperature, logging, and other functions. I wanted something simpler so I decided to create the code using a different baseline. I researched a bit more and ended using a combination of the HX711 SFE library and the original HX711 library.

Using this code base I was able to get the OpenScale board talking to the load cell fairly quickly and with good repeatable results.

It is essential to calibrate the “response” of the load cell used. Every load cell has a slightly different response. If one thinks of the load cell as a simple linear equation (i.e. y = m*x + b), then one needs to find the slope (m) and intercept (b) of the equation through calibration. Once this is obtained the load cell can be re-used repeatedly without further calibration. The code currently does this every time OpenScale is powered up. It will ask to calibrate the load cell, which will be necessary the first time the load cell is connected to OpenScale. Once the calibration cycle is completed, the power-up calibration cycle can just be ignored as the value previously used will be stored in EEPROM memory and will be used until a new (different) value is stored.

Putting it all Together

After connecting everything together following the SFE guide and some debugging of the code I was able to calibrate the scale and get readings that were both repeatable and that seemed reasonably accurate. A small physical prototype of the proto weight scale (base and pan) was created in a 3D CAD tool, it was then printed and assembled.

Code

Code:
/*
Example HX711 code using OpenScale
@languer 2018

This example demonstrates basic scale output. See the calibration sketch to get the calibration_factor for your

Arduino pin
3 -> HX711 CLK (modified to work with open scale, use pin 2 for HX711 breakout)
2 -> DAT (modified to work with open scale, use pin 3 for HX711 breakout)
5V -> VCC
GND -> GND

Board: Arduino/Genuino Uno
Programmer: AVR ISP
*/

/************************* HX711 Setup *********************************/
#include "HX711.h"
#define RESOLUTION  6     //decimal places of HX711 reading
#define AVG_FACT 8        //averagin factor of HX711 reading
#define DOUT  2           //data IO of HX711
#define CLK  3            //clock input of HX711
HX711 scale(DOUT, CLK);

/************************* EEPROM Setup *********************************/
#include <EEPROM.h>
byte eepCalFlag = 0;
long calibrationFactor_l = 535; //initial guess (for 0-5kg uxcell cell)

/************************* SETUP *********************************/
void setup() {
Serial.begin(9600);
Serial.println("OpenScale demo");
calibrateOpenScale();  // calibrate scale
delay(2500);
}

/************************* MAIN *********************************/
void loop() {
}

/************************* HX711 CALIBRATION *********************************/
void calibrateOpenScale() {
Serial.println("OpenScale calibration sketch");
Serial.println("Remove all weight from scale");
delay(5000);
Serial.println("After readings begin, place known weight on scale");
Serial.println("Press a to increase calibration factor by 10");
Serial.println("Press d to increase calibration factor by 100");
Serial.println("Press g to increase calibration factor by 1000");
Serial.println("Press z to decrease calibration factor by 10");
Serial.println("Press c to decrease calibration factor by 100");
Serial.println("Press b to decrease calibration factor by 1000");
Serial.println("Press x to exit calibration");
delay(5000);

//initialize calibration
//get cal value from eeprom if exists
if (eepCalFlag == 128) {
}
float calibrationFactor_f = calibrationFactor_l;

scale.set_scale();  //reset scale to default (0)
scale.tare();    //reset the scale to 0

Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
Serial.println(zero_factor);

boolean calibrateFlag = true;
while (calibrateFlag) {
scale.set_scale(calibrationFactor_f);  //Adjust to this calibration factor
Serial.print("Reading (grams, raw, cal factor): ");
Serial.print(scale.get_units(4), 3);
Serial.print(" , ");
Serial.print(" , ");
Serial.print(calibrationFactor_f);
Serial.println();

if (Serial.available()) {
if (temp == 'a') {
calibrationFactor_f += 10;
}
else if (temp == 'd') {
calibrationFactor_f += 100;
}
else if (temp == 'g') {
calibrationFactor_f += 1000;
}
else if (temp == 'z') {
calibrationFactor_f -= 10;
}
else if (temp == 'c') {
calibrationFactor_f -= 100;
}
else if (temp == 'b') {
calibrationFactor_f -= 1000;
}
else if (temp == 'x') {
calibrateFlag = false;
}
}
}

//exit calibration and store calibration in EEPROM
{
eepCalFlag = 128;
calibrationFactor_l = calibrationFactor_f;
Serial.println("Exiting calibration sequence");
}
}

Serial.print(scale.get_units(AVG_FACT), RESOLUTION); //scale.get_units() returns a float
Serial.print(" grams");  //grams or kilograms depending on load cell
Serial.println();
delay(1000);
}
• 127.6 KB Views: 239
• 683.9 KB Views: 241
• 1.5 MB Views: 231
• 322.3 KB Views: 225
• 197.2 KB Views: 221
• 70.4 KB Views: 220
Author
languer
Views
2,567
First release
Last update
Rating
0 ratings