IV Bag Monitor & Alerting System Using Load Cell and Arduino

Every year, countless patients in hospitals depend on intravenous (IV) drips for medication and hydration. Yet a surprisingly common problem persists — nurses miss the moment when an IV bag empties, which can cause air to enter the bloodstream or delay critical treatment. This project solves that with a simple, low-cost Arduino-based IV bag monitor that weighs the bag continuously and sounds a 5V siren buzzer the moment fluid drops below a safe threshold.

Overview

Monitoring intravenous fluid levels is one of the most repetitive yet critical tasks in any clinical environment. In busy wards where a single nurse may be responsible for a dozen patients, an empty IV bag can go unnoticed for precious minutes. The consequences range from mild — a delayed drip — to serious, including air embolism if the line runs dry.

This project presents a straightforward, low-cost solution: an IV Bag Monitor and Alerting System built around an Arduino microcontroller, a strain-gauge load cell, an HX711 24-bit analog-to-digital converter, a 16×2 LCD for live readout, and a 5V active siren buzzer for audible alerts. The total bill of materials is under roughly $10 USD, making it deployable even in resource-constrained healthcare settings.

The system continuously measures the weight of the hanging IV bag. As fluid drips into the patient, the weight decreases. When the weight falls below a user-defined threshold — say, the equivalent of 50 mL remaining — the Arduino triggers the siren buzzer, alerting staff before the bag runs completely empty. A real-time percentage display on the 16×2 LCD display module lets anyone glance at the remaining volume without any manual calculations.

Note: This is a prototype-level educational project intended for hobbyists, students, and engineers. It is not a certified medical device. Always follow your institution’s clinical protocols when deploying any monitoring aid.

Working Principle

IV Bag Monitor & Alerting System using Arduino and load cell output on LCD display connected IV stand

The system’s logic is elegantly simple — it treats the IV bag as a weight that decreases over time and raises an alarm when that weight crosses a critical lower boundary.

  1. The IV bag is hung from a hook attached to a load cell sensor. The load cell bears the entire weight of the bag plus any remaining fluid.
  2. As saline or medication drips through the IV tube, the bag gradually becomes lighter. The load cell detects this continuous decrease in force.
  3. The tiny voltage signal from the load cell (in the millivolt range) is sent to the HX711 module, which amplifies it and converts it to a clean 24-bit digital value.
  4. Arduino reads this digital value and, using a calibration factor, converts it into grams or milliliters (since 1 mL of saline ≈ 1 g).
  5. The calculated weight is displayed on the LCD in both grams and as a percentage of the original full-bag weight.
  6. When the remaining weight drops below the programmed alert threshold (e.g., 50 g), Arduino sends a HIGH signal to the 5V siren buzzer, which emits a loud continuous alarm until the bag is replaced and the system is reset.
Tip: You can set two thresholds — a first warning at 30% remaining (intermittent beep) and a critical alert at 10% remaining (continuous siren). This gives nurses advance notice and avoids sudden alarms.

Required Components

All components listed below are widely available on Amazon, Digikey, or any local electronics supplier:

Component Spec / Model Quantity
Arduino Nano/Uno ATmega328P 1
Load Cell 5 kg, bar-type 1
HX711 Module 24-bit ADC 1
16×2 LCD Display with I2C module (0x27) 1
5V Active Siren Buzzer Active type, 85+ dB 1
Jumper Wires M-M and M-F 20+
Breadboard 830-point 1
Important — Buzzer Type: Use an active siren buzzer (the kind that produces sound when you simply apply 5V DC). A passive buzzer requires a PWM tone signal from Arduino. The active type is plug-and-play and far louder, making it more suitable for clinical environments.

About the Load Cell

Before wiring anything up, it helps to truly understand how a load cell works — because calibration is the step most beginners get wrong, and understanding the physics makes calibration intuitive.

What Is a Load Cell?

load cell image

A load cell is a transducer — a device that converts mechanical force into an electrical signal. When you place a weight on a load cell, its internal metal body deforms ever so slightly. Bonded to that metal body are strain gauges: thin metallic foil patterns whose electrical resistance changes in proportion to how much they are stretched or compressed.

 

The Wheatstone Bridge

wheatstone Bridge inside a load cell

A standard bar-type load cell (the kind used in this project) contains four strain gauges arranged in a Wheatstone bridge circuit. When weight is applied, two gauges on the tensioned side of the metal bar stretch and their resistance increases, while the other two gauges on the compressed side see their resistance decrease. This push-pull imbalance across the bridge produces a differential output voltage — tiny, typically just a few millivolts per volt of excitation — that is directly proportional to the applied force.

Why We Need the HX711

The millivolt-level output from a load cell is far too small for Arduino’s 10-bit ADC to resolve meaningfully. The HX711 module solves this in two ways: it amplifies the differential signal by a programmable gain (64× or 128×) and then digitizes it using an internal 24-bit sigma-delta ADC, delivering a high-resolution reading over a simple two-wire serial interface to Arduino. This combination of amplification and precision conversion is what makes accurate weight measurement possible at low cost.

hx711 load cell amplifier pinout diagram

Wire Color Conventions

Wire Color Signal Connect to HX711 Pin
Red Excitation+ (E+) E+
Black Excitation− (E−) E−
White Signal- (A-) A-
Green Signal+ (A+) A+
Note: Some load cells include a fifth yellow wire — this is a shield ground and should be connected to the GND of HX711 or left unconnected. Wire colors can vary by manufacturer, so always verify against your datasheet.

Circuit Connections

Connect all the required components as shown in the below circuit diagram. The wiring involves three sub-connections: load cell → HX711, HX711 → Arduino, LCD (I2C) → Arduino, and the buzzer → Arduino.

IV Bag Monitor & Alerting System using Arduino and loadcell Circuit Diagram

 

Current Note: A 5V active siren buzzer can draw up to 30–40 mA. Arduino’s digital pins are rated for a maximum of 40 mA each. If your buzzer draws more (check the datasheet), drive it through a NPN transistor (such as the 2N2222 or BC547) with a 1kΩ base resistor, and power the buzzer directly from the 5V rail. This protects the Arduino pin from damage.

Attach the load cell to the IV drip stand like shown in the above circuit diagram, one end to the pole and another end hanging with the hook to attach the IV drip bag.


Build a Life-Saving IV Bag Monitor with PCBWay—Custom PCBs & 3D-Printed Enclosures for Your Load Cell & Arduino Project

Monitor fluid levels in real time and alert caregivers before an IV runs dry. PCBWay’s integrated manufacturing services help you transform your load cell and Arduino prototype into a reliable, ready-to-use monitoring system for healthcare training or assistive devices.

Custom PCB Manufacturing for Precision Weight Sensing:
PCBWay manufactures high-quality custom PCBs that consolidate your load cell amplifier (HX711), Arduino, buzzer, LED indicators, and wireless module onto a single compact board. Our PCBs feature clean analog traces to preserve microvolt-level load cell signals, dedicated power planes for stable excitation voltage, and noise-isolated layouts for accurate, drift-free readings. Choose our professional SMT assembly to receive a fully populated, tested board ready for calibration.

Durable 3D-Printed Enclosures for Hanging Systems:
Design and order a custom enclosure through PCBWay’s advanced 3D printing service. Create a lightweight, impact-resistant housing using ABS or PETG, featuring integrated hooks for IV pole mounting, a load cell pass-through slot, and a clear window for status LEDs. Add internal PCB bosses and battery compartments—all printed with precision to ensure secure, reliable operation in clinical or home settings.

Why PCBWay Delivers Professional Results:

  • Accurate Sensing: Precision PCB design preserves load cell signals for reliable weight tracking
  • Secure Mounting: Custom enclosures integrate hooks and cable management for hanging use
  • Seamless Integration: Perfect alignment between PCB and enclosure from one trusted source

Build Your IV Monitoring System Today:
Upload your PCB design and enclosure model for instant quotes, DFM feedback, and professional manufacturing at PCBWAY.COM


Program Code

Before uploading, install these two libraries via the Arduino IDE Library Manager (Sketch → Include Library → Manage Libraries):

  • HX711 by Bogdan Necula (or the popular fork by Rob Tillaart)
  • LiquidCrystal_I2C by Frank de Brabander
/*
 * IV Bag Monitor and Alerting System
 * Author  : Circuitschools
 */

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

// ── Pin Definitions ──────────────────────────────
const int HX711_DT_PIN  = 3;   // HX711 Data pin
const int HX711_SCK_PIN = 2;   // HX711 Clock pin
const int BUZZER_PIN    = 8;   // Active siren buzzer

// ── User Configuration ───────────────────────────
const float CALIBRATION_FACTOR = -420.0; // Adjust this after calibration
const float FULL_BAG_WEIGHT_G  = 500.0;  // Full IV bag weight in grams (e.g., 500mL bag)
const float WARN_THRESHOLD_G   = 150.0;  // Warning alert at 150g remaining (~30%)
const float CRIT_THRESHOLD_G   = 50.0;   // Critical alert at 50g remaining (~10%)

// ── Object Initialisation ────────────────────────
HX711              scale;
LiquidCrystal_I2C  lcd(0x27, 16, 2);   // Address 0x27, 16 cols, 2 rows

// ── Global State ─────────────────────────────────
bool alarmActive   = false;
bool warnTriggered = false;
unsigned long lastBeep = 0;

// ─────────────────────────────────────────────────
// SETUP
// ─────────────────────────────────────────────────
void setup() {
  Serial.begin(9600);
  pinMode(BUZZER_PIN, OUTPUT);
  digitalWrite(BUZZER_PIN, LOW);   // Ensure buzzer is off on start

  // Initialise LCD
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("IV BAG MONITOR");
  lcd.setCursor(0, 1);
  lcd.print("Initialising...");
  delay(2000);

  // Initialise HX711
  scale.begin(HX711_DT_PIN, HX711_SCK_PIN);
  scale.set_scale(CALIBRATION_FACTOR);
  scale.tare();   // Zero out any pre-load (bag hook, etc.)

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Hang IV Bag Now");
  delay(4000);   // Give time to hang the full bag
  lcd.clear();
}

// ─────────────────────────────────────────────────
// MAIN LOOP
// ─────────────────────────────────────────────────
void loop() {
  float weight  = scale.get_units(5);   // Average of 5 readings for stability
  if (weight < 0) weight = 0;           // Clamp negatives

  int percent = constrain(
    (int)((weight / FULL_BAG_WEIGHT_G) * 100), 0, 100
  );

  // ── Display on LCD ────────────────────────
  lcd.setCursor(0, 0);
  lcd.print("Weight: ");
  lcd.print(weight, 1);
  lcd.print(" g   ");

  lcd.setCursor(0, 1);
  lcd.print("Level: ");
  lcd.print(percent);
  lcd.print("%      ");

  // ── Serial Monitor Log ────────────────────
  Serial.print("Weight: ");
  Serial.print(weight);
  Serial.print(" g | Level: ");
  Serial.print(percent);
  Serial.println("%");

  // ── Alert Logic ───────────────────────────
  if (weight <= CRIT_THRESHOLD_G) {
    // CRITICAL: Continuous siren
    digitalWrite(BUZZER_PIN, HIGH);
    alarmActive = true;
    lcd.setCursor(14, 1);
    lcd.print("!!");
  }
  else if (weight <= WARN_THRESHOLD_G) {
    // WARNING: Intermittent beep every 3 seconds
    unsigned long now = millis();
    if (now - lastBeep >= 3000) {
      digitalWrite(BUZZER_PIN, HIGH);
      delay(300);
      digitalWrite(BUZZER_PIN, LOW);
      lastBeep = now;
    }
    lcd.setCursor(14, 1);
    lcd.print(" !");
  }
  else {
    // Normal operation — no alarm
    if (alarmActive) {
      digitalWrite(BUZZER_PIN, LOW);
      alarmActive = false;
    }
    lcd.setCursor(14, 1);
    lcd.print("  ");
  }

  delay(500);   // Update every 500ms
}
Calibration Step: After uploading the code, open the Serial Monitor, place a known weight on the load cell (e.g., a 200 g object), and adjust CALIBRATION_FACTOR until the displayed value matches the actual weight. Start with −420.0 and tune in increments of ±10 until accurate.

For Dedicated Calibration code check: here


Code Explanation

Library Includes and Pin Setup

The sketch begins by including three libraries. HX711.h handles all the serial communication with the HX711 ADC module. Wire.h enables the I2C protocol that the LCD uses to communicate with Arduino over just two wires (SDA and SCL). LiquidCrystal_I2C.h provides the higher-level API to print text on the display. The pin constants at the top make it easy to rewire the circuit without hunting through the code.

User Configuration Block

CALIBRATION_FACTOR is the key tuning variable — it translates raw HX711 counts into grams. FULL_BAG_WEIGHT_G stores the weight of a freshly hung, full IV bag (you weigh this first and enter it). The two threshold constants define at what remaining weight the warning beep triggers and at what weight the continuous critical alarm fires.

setup() Function

In setup(), the buzzer pin is initialised as an OUTPUT and explicitly set LOW to prevent false triggering on boot. The LCD is initialised and displays a startup message. Then scale.begin() starts communication with HX711, set_scale() applies the calibration factor, and critically, scale.tare() zeros out the scale — this is essential, because it subtracts the weight of the hook, the saline tube, and any other fixtures so only the bag’s fluid weight is measured.

get_units(5) — Averaged Readings

The get_units(5) call takes five successive readings from the HX711 and returns their average. This simple averaging step dramatically reduces noise in the weight measurement, which is important because load cells can be affected by building vibrations, air currents, and minor electrical interference.

Alert Logic — Two-Level Threshold

The if-else chain implements a two-stage alarm. When weight drops below CRIT_THRESHOLD_G (50 g by default), the buzzer pin goes permanently HIGH — continuous siren. If weight is between the warning and critical thresholds, the code uses millis() to implement a non-blocking 3-second interval beep, which lets the loop keep updating the display without blocking execution with delay(). When weight is above the warning threshold, the buzzer stays off.

Why millis() Instead of delay()?

Using delay(3000) for the warning interval would freeze the entire Arduino for 3 seconds between beeps — meaning the LCD would not update, and you could miss the transition from warning to critical. The millis() approach lets the loop run freely and only triggers the beep when the elapsed time exceeds 3000 milliseconds.


Applications

While this project is designed for IV bag monitoring, the underlying principle — weigh something continuously and alert when the weight drops below a threshold — is broadly applicable:

Hospital IV Drip Rooms

Automatically alert nurses when any IV bag nears empty, reducing manual rounds.

Home Patient Care

Caretakers managing patients at home can rely on the alert instead of constant supervision.

Lab Fluid Dispensing

Monitor reagent containers and trigger restocking alerts before a process is interrupted.

Industrial Fluid Control

Monitor lubricant or coolant reservoirs in machinery and alert when levels are low.

Smart Inventory Weighing

Track bulk material consumption (powders, grains) by weight and auto-log refills.

Expand this project: Add an ESP8266 or SIM800L module to send SMS or push notifications to a nurse’s phone when the alarm triggers — turning this local alert system into a full IoT monitoring solution without changing the core hardware significantly.

Related project: Weighing scale using load cell and HX711 amplifier with Arduino


Frequently Asked Questions:

On hx711 is A+ is white and A- is green, as we seen different on different sites?

The question stated White = A+ and Green = A−, but that is incorrect according to the most authoritative sources. Here’s what they actually say:

Source A+ (Signal +) A− (Signal −)
SparkFun (official guide) Green (or Blue) sparkfun White sparkfun
Adafruit (official pinouts) Green wire → A+ Adafruit White wire → A− Adafruit
Robocraze Green = A+, White = A− Robocraze
Circuit Journal Green → A+, White → A− Circuit Journal

So the correct standard is:

Green → A+ (Signal Positive)
White → A− (Signal Negative)

Does It Actually Matter If Swapped?

The polarity of the load cell signal wires isn’t critical — if you accidentally swap white and green (A+ and A−), the system will still work, but the readings will decrease as weight increases instead of increasing. You’d fix this in software by making the calibration factor positive instead of negative.

So swapping them won’t damage anything — you’d just see the weight go in the wrong direction on the Serial Monitor, and flipping the sign of CALIBRATION_FACTOR corrects it instantly.


Conclusion

Building an IV Bag Monitor and Alerting System with an Arduino, load cell, HX711, and 5V siren buzzer is one of those projects where simple electronics genuinely solve a real-world problem. The system is inexpensive, easy to assemble on a breadboard in an afternoon, and immediately understandable to anyone who sees it in action.

The key takeaways from this build are how a strain-gauge load cell converts weight into a differential voltage, how the HX711’s 24-bit ADC bridges the gap between that millivolt signal and Arduino’s digital world, and how the tare function is the often-overlooked step that makes the readings meaningful. With proper calibration, this system can resolve weight changes of as little as 1–2 grams — well within the precision needed to catch an IV bag transitioning from “nearly empty” to “empty.”

Whether you build this as a student project, an engineering prototype, or a stepping stone toward a fully IoT-connected hospital monitoring system, the principles you learn here — weight sensing, threshold-based alerting, and non-blocking code structure — will serve you in countless future embedded systems projects.

Have questions about calibration or expanding this project with Wi-Fi alerting? Drop a comment below — and don’t forget to share this guide with anyone working on Arduino medical electronics projects.

Add a Comment

Leave a Reply

Your email address will not be published. Required fields are marked *