Project showcase
High Precision Scale with Arduino

High Precision Scale with Arduino © LGPL

This is a very precise scale for any weight up to 1.5 kg!

  • 8,263 views
  • 13 comments
  • 35 respects

Components and supplies

Necessary tools and machines

Saw
3drag
3D Printer (generic)

Apps and online services

About this project

This is one of my very first Arduino projects. This is a high precision scale based on the HX711 module, with different operating modes.

It can measure weight in the normal mode:

Count coins that are placed on top, one by one:

There's also a mode where you can place a coin and the program will calculate its weight. You can then place as many coins as you want, either one by one or all together, and the scale calculates the amount of money and how many coins were placed on top.

The same works for any other item and this mode is called "items mass."

Here is a video tutorial how to build one. It is in Russian, but I hope you will still enjoy it!

Code

The codeC/C++
This code might be not the best written one, but please remember that this was one of my very first projects!
#include <LiquidCrystal_I2C.h>
#include <HX711.h>

HX711 scale(A1, A0); 
LiquidCrystal_I2C lcd(0x3F,16,2);


// 
volatile float newWeight;
volatile float prevWeight;
volatile float money;
volatile float item;
volatile float change;
volatile float flag;
volatile int show = 1;
volatile float itemWeight;
volatile int amount;

int tara = 4;
unsigned long int lastTime;

int up = 2;
int down = 3;
volatile int pos = 1;


void setup() {
  lcd.init();                                         //   
  lcd.backlight();                                    //  
  scale.set_scale(-1537.34);                          //    (   )
  scale.tare();                                       //  
  prevWeight = 0;                                     //    
  scale.power_up();

  Serial.begin(9600);
  
  pinMode(tara, INPUT);
  pinMode(up, INPUT);
  attachInterrupt(0, dec, RISING);
  pinMode(down, INPUT);
  attachInterrupt(1, inc, RISING);

}

void myClear() {
    lcd.setCursor(0,0);
    lcd.print("                ");
    lcd.setCursor(0,1);
    lcd.print("                ");
    lcd.setCursor(0,0);
  }

void reload() {
  prevWeight = 0;
  newWeight = 0;
  money = 0;
  item = 0;
  change = 0;
  show = 1;
}

void dec() {
  reload();
  if (pos > 1) {
    pos -= 1; 
  }
  else {
    pos = 4;  
  }
}

void inc() {
  reload();
  if (pos < 4) {
    pos += 1;  
  }
  else {
    pos = 1;  
  }    
}

void analysis() {
  if (change > 1.00 && change < 2.40) {               // 1c           
    money += 1;
    flag = 1.25;
  }
  else if (change > 2.80 && change < 3.15) {          // 2c
    money += 2;
    flag = 2.50;
  }
  else if (change > 3.70 && change < 3.99) {          // 5c
    money += 5;
    flag = 3.80;
  }
  else if (change > 4.00 && change < 4.15) {          // 10c
    money += 10;
    flag = 4;
  }
  else if (change > 5.50 && change < 6.80) {          // 20c
    money += 20;
    flag = 6;
  }
  else if (change > 7.60 && change < 7.95) {          // 50c
    money += 50;
    flag = 7.80;
  }
  else if (change > 7.30 && change < 7.50) {          // 1E
    money += 100;
    flag = 7.40;
  }
  else if (change > 8.20 && change < 9.00) {          // 2E
    money += 200;
    flag = 8.50;
  }
}

//  :
void standard() {
  lcd.setCursor(0,0);
  lcd.print(" Standard mode! "); 
  lcd.setCursor(0,1);                                 //    1  2 !
  lcd.print("Weight: ");
  if (prevWeight != round(scale.get_units(10)) ) {     //   ,
    newWeight = scale.get_units(10);                   //     
  }
  lcd.setCursor(9,1);
  if (newWeight < 0) { scale.tare(); }
  else { lcd.print(newWeight); }
  prevWeight = newWeight;                             //    

}
///////////////////////////////////

void multiMoney() {
  lcd.setCursor(0,0);
  lcd.print("  Money multi!  ");
  lcd.setCursor(0,1);
  lcd.print("Euro: ");
  if (prevWeight != round(scale.get_units(10)) ) {    
    newWeight = scale.get_units(10);
    change = newWeight - prevWeight;
    analysis();
    lcd.setCursor(6,1);
    lcd.print(money / 100.00);
    prevWeight = newWeight;          
  }
}
//////////////////////////////////////////

void massMoney() {
  if (prevWeight != round(scale.get_units(20)) ) {    
    newWeight = scale.get_units(20); 
    change = newWeight - prevWeight;
    prevWeight = newWeight;
    if (change > 1) {
      lcd.setCursor(0,1);
      lcd.print("C:");
      lcd.setCursor(2,1);
      lcd.print(show);
      lcd.setCursor(7,1);
      lcd.print("A:");
      lcd.setCursor(10,1);
      lcd.print(show * money / 100);
      show = show + round(change / flag);  
    }
  }
}
//////////////////////////////////////

void itemsMass() {
  if (prevWeight != round(scale.get_units(10)) ) {    
    newWeight = scale.get_units(10);
    change = newWeight - prevWeight;
    amount = round(change / itemWeight);
    lcd.setCursor(0,1);
    lcd.print("Items: ");
    lcd.print(amount);
    lcd.setCursor(9,1);
    lcd.print("W:");
    lcd.print(newWeight);
  }
}
//////////////////////////////////////////


void loop() {
  if (millis() - lastTime > 100) {
    if (digitalRead(tara) == 1) {
      reload();
      scale.tare();
    }
    lastTime = millis();
  }
  
  if (pos == 1) {
    myClear();
    lcd.setCursor(4,0); 
    lcd.print("Standard");
    delay(1000);
    myClear();
    while (pos == 1) {
      standard();
    } 
  }

  else if (pos == 2) {
    myClear();
    lcd.setCursor(3,0);
    lcd.print("Money multi");
    delay(1000);
    myClear();
    while (pos == 2) {
      multiMoney();  
    }
  }

  else if (pos == 3) {
    myClear();
    lcd.setCursor(3,0);
    lcd.print("Money mass");
    delay(1000);
    myClear();
    lcd.print("Place ONE coin!"); 
    while (money == 0) {
      if (prevWeight != round(scale.get_units(10)) ) {    
        newWeight = scale.get_units(10);
        change = newWeight - prevWeight;
        analysis();
        lcd.setCursor(0,1);
        lcd.print(money / 100);
        prevWeight = newWeight;          
      }
    }
    myClear();
    lcd.print("Counting ");
    if (money < 100) {
      lcd.setCursor(10,0);
      lcd.print(money);
      lcd.print("c");
    }
    else {
      lcd.setCursor(10,0);
      if (money == 100) { lcd.print("1 Euro"); }
      else { lcd.print("2 Euro"); }
    }
    prevWeight = 0;
    newWeight = 0;
    change = 0;
    while (pos == 3) {
      massMoney();
    }
  }
  

  else if (pos == 4) {
    myClear();
    lcd.setCursor(3,0);
    lcd.print("Items mass");
    delay(1000);
    myClear();
    myClear();
    lcd.print("Place ONE item!");
    while (newWeight < 1) {
      if (prevWeight != round(scale.get_units(10)) ) {    
        newWeight = scale.get_units(10);
        itemWeight = newWeight - prevWeight;
      }
    }
    itemWeight = newWeight - prevWeight;
    lcd.setCursor(0,0);
    lcd.print("Item weight:");
    lcd.print(itemWeight);
    while (pos == 4) {
      itemsMass();
    }
  }
}

Custom parts and enclosures

The 3d model, altough it is just a prototype.
smartscale2_3H1uQXRu31.skp

Schematics

The connection of the HX711 module
Hx711 81dd9avmtl
HX711 Library
hx711_yQq2ToCJp3.zip

Comments

Similar projects you might like

Arduino UNO High Precision Counting Scale

Project showcase by Fedeasche

  • 13,115 views
  • 9 comments
  • 43 respects

FizViz - Large Scale Physical Visualizations for Your Stats!

Project tutorial by Team IoT Design Shop

  • 20,823 views
  • 11 comments
  • 83 respects

eDOT - Arduino Based Precision Clock and Weather Station

Project tutorial by antiElectron

  • 9,500 views
  • 4 comments
  • 25 respects

Arduino-based Digital Scale with HX711 and VFD Display

Project showcase by antiElectron

  • 4,542 views
  • 0 comments
  • 20 respects

Automated Password Typer

Project showcase by mPelectronic

  • 9,579 views
  • 22 comments
  • 32 respects

Rampiot - Cool Smart Lock

Project tutorial by Robinson Mesino

  • 3,873 views
  • 1 comment
  • 23 respects
Add projectSign up / Login