Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

Arduino UNO-Based Smart Weight Measurement System with Load Cell, LCD Display, and Servo Control

View and Edit Project In Cirkit DesignerImage of Arduino UNO-Based Smart Weight Measurement System with Load Cell, LCD Display, and Servo Control

Circuit Documentation

Summary

This circuit is designed to measure the weight of an item using a load cell and display the weight on an LCD screen. It also uses a servo motor to sort items based on their weight. The circuit includes a push button to toggle between two sets of weight limits. The main controller for this circuit is an Arduino UNO.

Component List

  1. SparkFun Load Cell Amplifier - HX711

    • Description: Amplifies the signal from the load cell.
    • Pins: GND, CLK, DAT, VCC, YLW, GRN, WHT, BLK, RED, B-, B+
  2. 16x2 I2C LCD

    • Description: Displays weight and status messages.
    • Pins: GND, VCC, SDA, SCL
  3. MG996R Servo Motor

    • Description: Moves to indicate the status of the item (OK or Defect).
    • Pins: GND, VCC, SIG
  4. Arduino UNO

    • Description: Main microcontroller for the circuit.
    • Pins: UNUSED, IOREF, Reset, 3.3V, 5V, GND, Vin, A0, A1, A2, A3, A4, A5, SCL, SDA, AREF, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0
  5. Load Cell - Red/white/black/green

    • Description: Measures the weight of the item.
    • Pins: E+, A-, E-, A+
  6. Push Button Round

    • Description: Toggles between two sets of weight limits.
    • Pins: leg0, leg1

Wiring Details

SparkFun Load Cell Amplifier - HX711

16x2 I2C LCD

MG996R Servo Motor

Arduino UNO

Load Cell - Red/white/black/green

Push Button Round

Documented Code

Arduino UNO Code

#include <HX711.h>
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Pin definitions
const int LOADCELL_DOUT_PIN = A1;
const int LOADCELL_SCK_PIN = A0;
const int SERVO_PIN = 9;
const int BUTTON_PIN = 2; // Pin for the push button

// Load cell and servo objects
HX711 scale;
Servo myServo;

// LCD object
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Weight limits for item
const float ITEM_MIN_WEIGHT_DEFAULT = 50.0; // Default minimum acceptable weight in grams
const float ITEM_MAX_WEIGHT_DEFAULT = 150.0; // Default maximum acceptable weight in grams
const float ITEM_MIN_WEIGHT_ALTERNATE = 30.0; // Alternate minimum acceptable weight in grams
const float ITEM_MAX_WEIGHT_ALTERNATE = 100.0; // Alternate maximum acceptable weight in grams

// Calibration factor for the load cell (update this with your calibrated value)
const float CALIBRATION_FACTOR = 1684.81; // Adjust this value based on your calibration

// Threshold to consider the weight as significant
const float WEIGHT_THRESHOLD = 5.0; // Adjust this value based on your setup

// Button state variables
bool buttonState = HIGH; // Current state of the button
bool lastButtonState = LOW; // Previous state of the button
bool useAlternateLimits = false; // Flag to use alternate weight limits
unsigned long lastDebounceTime = 0; // The last time the output pin was toggled
unsigned long debounceDelay = 50; // The debounce time; increase if the output flickers

// Timing variables
unsigned long lastMeasurementTime = 0; // Last time weight was measured
const unsigned long measurementInterval = 500; // Interval for weight measurement

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Initialize load cell
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.set_scale(CALIBRATION_FACTOR); // Set the calibration factor
  scale.tare(); // Reset the scale to 0

  // Initialize servo
  myServo.attach(SERVO_PIN);
  myServo.write(90); // Initial position (neutral)

  // Initialize LCD
  lcd.init();
  lcd.backlight();

  // Initialize button pin
  pinMode(BUTTON_PIN, INPUT_PULLUP); // Use internal pull-up resistor

  // Display initial message
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Ready....");
  delay(1000);
}

void loop() {
  // Read the button state
  int reading = digitalRead(BUTTON_PIN);

  // Check for button state change with debounce
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == LOW) { // Button pressed
        useAlternateLimits = !useAlternateLimits; // Toggle weight limit variant

        // Display message when switching variants
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Menggunakan");
        lcd.setCursor(0, 1);
        if (useAlternateLimits) {
          lcd.print("Variasi 2");
        } else {
          lcd.print("Variasi 1");
        }
        delay(1000); // Display message for 1 second
      }
    }
  }

  lastButtonState = reading;

  // Measure weight at defined intervals
  if (millis() - lastMeasurementTime >= measurementInterval) {
    lastMeasurementTime = millis();

    // Set weight limits based on the current variant
    float ITEM_MIN_WEIGHT = useAlternateLimits ? ITEM_MIN_WEIGHT_ALTERNATE : ITEM_MIN_WEIGHT_DEFAULT;
    float ITEM_MAX_WEIGHT = useAlternateLimits ? ITEM_MAX_WEIGHT_ALTERNATE : ITEM_MAX_WEIGHT_DEFAULT;

    // Measure weight
    float weight = scale.get_units(10);

    // Display weight on LCD
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Weight: ");
    if (abs(weight) < 0.95) { // If the weight is very close to zero, display 0 grams
      lcd.print("0.00");
    } else {
      lcd.print(weight, 2);
    }
    lcd.print(" g");

  // Check if weight is above the threshold
  if (weight > WEIGHT_THRESHOLD) {
    // Check if weight is within limits
    if (weight < ITEM_MIN_WEIGHT || weight > ITEM_MAX_WEIGHT) {
      lcd