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.
Table of Contents
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.
Working Principle

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.
- 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.
- As saline or medication drips through the IV tube, the bag gradually becomes lighter. The load cell detects this continuous decrease in force.
- 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.
- Arduino reads this digital value and, using a calibration factor, converts it into grams or milliliters (since 1 mL of saline ≈ 1 g).
- The calculated weight is displayed on the LCD in both grams and as a percentage of the original full-bag weight.
- 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.
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 |
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?

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

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.

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+ |
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.

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
}
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.
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.
